2014-02-14 5 views
4

Я новичок. Ниже мой html & Код js. Когда я нажимаю «Добавить» друга,Как заставить AngularJS переключаться между представлениями и показывать обновленный список

  1. $ scope.friends list не обновляется. Я получаю undefined для $ scope.newFriend.name, $ scope.newFriend.age и т. Д.
  2. Также как перезагрузить view1, чтобы показать обновленный список.

----- ----- main.html

<!doctype> 
<html> 
<body> 
<div ng-app="demoApp" ng-controller="FriendsController"> 
    <input type="text" ng-model="name"> 
    <p>I'am {{name}} have {{friends.length}} friends. </br>They are:</p> 
    <input type="search" ng-model="search" placeholder="Find by name/age/gender" /> | <a href="#/add">Add Friend</a> 
    <div ng-view></div> 
</div> 
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular.min.js">  </script> 
<script src="Scripts/angular-route.js"></script> 
<script> 
var demoApp = angular.module('demoApp', ['ngRoute']); 

demoApp.config(['$routeProvider', 
    function($routeProvider) { 
$routeProvider. 
    when('/', { 
    templateUrl: 'view1.html', 
    controller: 'FriendsController' 
    }). 
    when('/add', { 
    templateUrl: 'view2.html', 
    controller: 'FriendsController' 
    }). 
    otherwise({ 
    redirectTo: '/' 
    }); 
}]); 

demoApp.controller('FriendsController', function($scope){ 
$scope.name = "Joeey"; 
$scope.newFriend = {}; 
    $scope.friends = [ 
    {name:'John', age:25, gender:'boy', sal :100}, 
    {name:'Jessie', age:30, gender:'girl'}, 
    {name:'Johanna', age:28, gender:'girl'}, 
    {name:'Joy', age:15, gender:'girl'}, 
    {name:'Mary', age:28, gender:'girl'}, 
    {name:'Peter', age:95, gender:'boy'}, 
    {name:'Sebastian', age:50, gender:'boy'}, 
    {name:'Erika', age:27, gender:'girl'}, 
    {name:'Pabtrgick1', age:40, gender:'boy'}, 
    {name:'Pabtrgick2', age:40, gender:'girl'}, 
    {name:'Samantha', age:60, gender:'girl'} 
]; 

$scope.addFriend = function(){ 
    $scope.friends.push({ 
    name : $scope.newFriend.name, 
    age : $scope.newFriend.age, 
    gender : $scope.newFriend.gender 
    }) 
    console.log($scope.friends); 
} 
}); 

</script> 
</body> 
</html> 

---- view1.html ---

<ul> 
<li ng-repeat="f in friends | filter:search | orderBy:'name'"> 
    [{{$index + 1}}] {{f.name | lowercase}} - {{f.gender | uppercase}} is {{f.age}} years old & salary is {{f.sal}}. 
</li> 
</ul> 

- - view2.html ---

<br/>Name: <input type="text" ng-bind="newFriend.name" /> 
<br/>Age: <input type="text" ng-bind="newFriend.age" /> 
<br/>Gender: <input type="text" ng-bind="newFriend.gender" /> 
<br/><button ng-click="addFriend()">Add</button> 

---- EDIT (метод добавлен завод & модифицированный FriendsController) ---

demoApp.factory('friendsFactory', function(){ 
var friends = [ 
    {name:'John', age:25, gender:'boy', sal :100}, 
    {name:'Jessie', age:30, gender:'girl'}, 
    {name:'Johanna', age:28, gender:'girl'}, 
    {name:'Joy', age:15, gender:'girl'}, 
    {name:'Mary', age:28, gender:'girl'}, 
    {name:'Peter', age:95, gender:'boy'}, 
    {name:'Sebastian', age:50, gender:'boy'}, 
    {name:'Erika', age:27, gender:'girl'}, 
    {name:'Pabtrgick1', age:40, gender:'boy'}, 
    {name:'Pabtrgick2', age:40, gender:'girl'}, 
    {name:'Samantha', age:60, gender:'girl'} 
]; 
var factory = {}; 
factory.getFriends = function(){ return friends}; 

return factory; 
}); 


demoApp.controller('FriendsController', function($scope, $location, friendsFactory){ 
$scope.name = "Joeey"; 
    $scope.friends = friendsFactory.getFriends(); 

$scope.addFriend = function(){ 
    $scope.friends.push({ 
    name : $scope.newFriend.name, 
    age : $scope.newFriend.age, 
    gender : $scope.newFriend.gender 
    }) 
    $location.url('/') 
} 
}); 
+1

Я думаю, что ваши два вида получают разные экземпляры контроллера. Если вы хотите поделиться данными, вы должны сохранить их в службе. Кроме того, для двусторонней привязки используйте ng-model not ng-bind. –

ответ

2

1). Вы действительно должны разделять проблемы. Перечисление друзей и добавление нового - должно быть лучше обработано двумя разными контроллерами: FriendsController и NewFriendController.

2). Совместное использование массива друзей в этом случае было бы идеальным с пользовательской услугой, скажем Friends.

3). Вместо ng-bind вы хотите использовать ng-model, чтобы иметь возможность передавать данные формы обратно контроллеру.

4). И, наконец, для перенаправления на другой маршрут используйте услугу $location: $locations.route('/').

Это может выглядеть следующим образом:

demoApp.factory('Friends', function() { 
    var friends = [{ 
     name: 'John', 
     age: 25, 
     gender: 'boy', 
     sal: 100 
    }]; 
    return { 
     getAll: function() { 
      return friends; 
     }, 
     addNew: function(friend) { 
      friends.push(friend); 
      return this.getAll(); 
     } 
    }; 
}); 

demoApp.controller('FriendsController', function($scope, Friends) { 
    $scope.name = "Joeey"; 
    $scope.friends = Friends.getAll(); 
}); 

demoApp.controller('NewFriendController', function($scope, Friends, $location) { 
    $scope.addFriend = function() { 
     Friends.addNew($scope.newFriend); 
     $location.path('/'); 
    } 
}); 

Демо: http://plnkr.co/edit/1fPCavXuqhkyH2lrue2c?p=preview

Теперь, когда у вас есть Friends сервис это будет легко расширить функциональные возможности и использовать удаленную базу данных, REST API и т.д.

0

При изменении значения осциллографа, вам нужно $ применить изменения.

$scope.addFriend = function(){ 
    $scope.$apply(function() { 
     $scope.friends.push({ 
       name : $scope.newFriend.name, 
       age : $scope.newFriend.age, 
       gender : $scope.newFriend.gender 
     }); 
    }); 
} 
+0

Спасибо. добавление применяется, как вы сказали, с ошибкой «Ошибка: [$ rootScope: inprog] $ применяется уже в процессе». Я считаю, что это не правильное решение. Я добавил метод фабрики для хранения данных. теперь это сработало. Я обновил свой вопрос с помощью решения. – user2300875

+0

Функции, выполняемые из ng-click, уже выполняются в цикле дайджеста, вызов $ apply() не требуется. –

1

Вы ошибка всего в опечатках, проверьте Angular Docs

  1. Чтобы связать входные значения угловых $scope переменных, которые необходимо использовать ng-model атрибут вместо ng-bind. ng-bind используется только для печати значений, ng-model делает именно то, что вы хотите.

  2. Чтобы загрузить view1 после того, как добавили друга, вы можете позвонить в $location.url('/') у вас $scope.addFriend метод. Не забудьте ввести $location в ваш контроллер

+0

just-boris & Craig Squire, Спасибо, что указали это, я изменил ng-bind на модель, добавил местоположение и добавил фабричный метод для хранения данных. Как заметил Крейг, взгляды получают разные экземпляры контроллера. – user2300875

2

У вас есть два представления, получающие разные экземпляры контроллера. Если вы хотите поделиться данными, вы должны сохранить их в службе или снять объявления контроллера с ваших представлений и просто оставить ng-контроллер верхнего уровня (рядом с атрибутом ng-app).

Кроме того, для двусторонней привязки используйте ng-model not ng-bind, последняя предназначена только для модели -> просмотр обновлений, не полезная для элементов ввода.

Проверить это ...

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

http://plnkr.co/edit/LCPM8hCp43093Hu64Igt

Как другие говорили, наконец, придать $ расположение и использование $ location.path ('/') в addFriend(), чтобы вернуться к view1.

Смежные вопросы