AngularJS: Как я могу переключить виды из функции контроллера?

237

Я пытаюсь использовать нг-клик функцию AngularJS для переключения видов. Как бы я поступил так с кодом ниже?

index.html

 <div ng-controller="Cntrl">
        <div ng-click="someFunction()">
            click me
        <div>
    <div>

controller.js

  function Cntrl ($scope) {
        $scope.someFunction = function(){
            //code to change view?
        }
    }
The_Brink
источник

Ответы:

314

Чтобы переключаться между различными представлениями, вы можете напрямую изменить window.location (используя службу $ location!) В файле index.html.

<div ng-controller="Cntrl">
        <div ng-click="changeView('edit')">
            edit
        </div>
        <div ng-click="changeView('preview')">
            preview
        </div>
</div>

Controller.js

function Cntrl ($scope,$location) {
        $scope.changeView = function(view){
            $location.path(view); // path not hash
        }
    }

и настройте маршрутизатор для переключения на разные партиалы в зависимости от местоположения (как показано здесь https://github.com/angular/angular-seed/blob/master/app/app.js ). Это принесет пользу как истории, так и использованию ng-view.

В качестве альтернативы вы используете ng-include с другими частями, а затем используете ng-switch, как показано здесь ( https://github.com/ganarajpr/Angular-UI-Components/blob/master/index.html )

ganaraj
источник
Я получаю сообщение об ошибке, в котором говорится, что хэш не является функцией $ location.
The_Brink
Я не вижу хеш как часть объекта $ location, но есть переменная хеша $$, так что она и если да, то не работает.
The_Brink
ОК, я узнал, как это сделать. $ location.path (вид); ( docs.angularjs.org/guide/dev_guide.services.$location )
The_Brink
@The_Brink Спасибо за редактирование. Я не знаю, почему это было отклонено. Я внес изменения, чтобы отразить то, что я пытался сказать.
Ганарадж
2
На самом деле, лучше всего сделать нормальную ссылку. <a href="https://stackoverflow.com/edit">Edit</a> Angular примет меры, чтобы щелчок не создавал перезагрузку страницы. Это поведение может быть изменено так, что оно вызывает перезагрузку, если это необходимо.
Энтони Мартин
38

Предоставленный ответ является абсолютно правильным, но я хотел бы расширить для любых будущих посетителей, которые могут захотеть сделать это более динамично -

По мнению -

<div ng-repeat="person in persons">
    <div ng-click="changeView(person)">
        Go to edit
    <div>
<div>

В контроллере -

$scope.changeView = function(person){
    var earl = '/editperson/' + person.id;
    $location.path(earl);
}

Та же самая базовая концепция, что и принятый ответ, просто добавление в нее динамического контента, чтобы немного улучшить. Если принятый ответ захочет добавить это, я удалю свой ответ.

PW Kad
источник
8
в общей сложности придираться, но FYI, urlна самом деле полный веб - адрес, в том числе протокола (HTTP: //) и все. Как следует из $location.path()вашей переменной лучше описать как path.
Зак Лысобей
Но для этого требуется $ rootScope. $ Digest (); или $ scope. $ apply (); чтобы заставить его двигаться без задержки.
Раз
23

У меня есть пример работы.

Вот как выглядит мой документ:

<html>
<head>
    <link rel="stylesheet" href="css/main.css">
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.min.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular-resource.min.js"></script>
    <script src="js/app.js"></script>
    <script src="controllers/ctrls.js"></script>
</head>
<body ng-app="app">
    <div id="contnr">
        <ng-view></ng-view>
    </div>
</body>
</html>

Вот как выглядит мой фрагмент:

<div id="welcome" ng-controller="Index">
    <b>Welcome! Please Login!</b>
    <form ng-submit="auth()">
        <input class="input login username" type="text" placeholder="username" /><br>
        <input class="input login password" type="password" placeholder="password" /><br>
        <input class="input login submit" type="submit" placeholder="login!" />
    </form>
</div>

Вот как выглядит мой Ctrl:

app.controller('Index', function($scope, $routeParams, $location){
    $scope.auth = function(){
        $location.url('/map');
    };
});

приложение мой модуль:

var app = angular.module('app', ['ngResource']).config(function($routeProvider)...

Надеюсь, это полезно!

Cody
источник
12

Метод, использованный для всех предыдущих ответов на этот вопрос, предлагает изменить URL-адрес, который не является необходимым, и я думаю, что читатели должны знать об альтернативном решении. Я использую ui-router и $ stateProvider, чтобы связать значение состояния с templateUrl, который указывает на html-файл для вашего просмотра. Тогда это просто вопрос внедрения $ state в ваш контроллер и вызова $ state.go ('state-value') для обновления вашего представления.

В чем разница между angular-route и angular-ui-router?

Гэвин Палмер
источник
5

Для этого есть два пути:

Если вы используете ui-router или $stateProvider, сделайте это как:

$state.go('stateName'); //remember to add $state service in the controller

если вы используете angular-router или $routeProvider, сделайте это:

$location.path('routeName'); //similarily include $location service in your controller
Сухминдер Пармар
источник
Одна вещь, которая меня смутила, это использование имени маршрута вместо названия штата ... то есть оно должно быть "main" вместо "/ main"
Бен Шмидт
3

Без полной модернизации среды маршрутизации по умолчанию (# / ViewName) я смог немного изменить подсказку Коди и заставить ее работать великолепно.

контроллер

.controller('GeneralCtrl', ['$route', '$routeParams', '$location',
        function($route, $routeParams, $location) {
            ...
            this.goToView = function(viewName){
                $location.url('/' + viewName);
            }
        }]
    );

вид

...
<li ng-click="general.goToView('Home')">HOME</li>
...

Что привело меня к этому решению, так это то, что когда я пытался интегрировать виджет пользовательского интерфейса Kendo Mobile в угловую среду, я терял контекст моего контроллера, а поведение обычного тега привязки также было угнано. Я восстановил свой контекст из виджета Kendo, и мне нужно было использовать метод для навигации ... это сработало.

Спасибо за предыдущие посты!

beauXjames
источник
2
Firstly you have to create state in app.js as below

.state('login', {
      url: '/',
      templateUrl: 'views/login.html',
      controller: 'LoginCtrl'
    })

and use below code in controller

 $location.path('login'); 

Надеюсь, что это поможет вам

Вайшали Текале
источник
2

Эта маленькая функция хорошо послужила мне:

    //goto view:
    //useage -  $scope.gotoView("your/path/here", boolean_open_in_new_window)
    $scope.gotoView = function (st_view, is_newWindow)
    {

        console.log('going to view: ' + '#/' + st_view, $window.location);
        if (is_newWindow)
        {
            $window.open($window.location.origin + $window.location.pathname + '' + '#/' + st_view, '_blank');
        }
        else
        {
            $window.location.hash = '#/' + st_view;
        }


    };

Вам не нужен полный путь, только вид, на который вы переключаетесь

Шон Дотей
источник