Представление не обновляется при обновлении модели в AngularJS
Я прочитал темы по этой теме, такие как: В AngularJS не обновляется вид, но я до сих пор не могу понять, как применить его на моем простом примере.
У меня есть эта функция:
function MyPageView($scope) {
var myModel = new MyModel();
$scope.myModel = myModel;
}
когда myModel
обновляется в другом месте кода (когда пользователь щелкает, взаимодействует, отправляет запросы XHR), он не обновляет мое представление. Я понимаю, что мне нужно что-то сделать с помощью $apply, но я не понимал, где и как.
Может кто-нибудь объяснить мне, как решить эту проблему для этого простого случая использования?
Моя модель выглядит примерно так (если это необходимо для вопроса) - внутри нее нет кода AngularJS:
var MyModel = function() {
var _this = this;
...
_this.load = function(){...};
_this.updateModel = function(){...};
...
return _this;
}
добавить пример JSfiddle: http://jsfiddle.net/DAk8r/2/
Ответы
Ответ 1
Суть вашей проблемы в том, что вы пытаетесь смешивать AngularJS с очень традиционным шаблоном JavaScript jQuery-soup style. В Angular вы всегда должны использовать директивы для манипуляции и взаимодействия с DOM (включая клики). В этом случае ваш код должен выглядеть следующим образом:
<div ng-controller="myModelCtrl">
<div>Number is {{myModel.number}}</div>
<a ng-click="myModel.updateNumber()">Update Number</a>
</div>
function myModelCtrl($scope) {
var myModel = new MyModel();
$scope.myModel = myModel;
}
function MyModel() {
var _this = this;
_this.number = 0;
_this.updateNumber = function() {
_this.number += 1;
alert('new number should display ' + _this.number);
}
return _this;
}
Обратите внимание, что вместо настройки ручного обработчика click
с jQuery мы используем Angular встроенную директиву ng-click
. Это позволяет нам привязываться к жизненному циклу области Angular и правильно обновлять представление, когда пользователь нажимает на ссылку.
Вот цитата из Часто задаваемых вопросов по AngularJS; Я выделил часть, которая может помочь вам нарушить привычку.
Общие ошибки
Поддерживающий канал Angular (#angularjs on Freenode) видит ряд повторяющихся ошибок, с которыми сталкиваются новые пользователи Angular. Этот документ призван указать на них, прежде чем вы обнаружите их в трудном положении.
Манипуляция DOM
Остановите попытку использования jQuery для изменения DOM в контроллерах. В самом деле. Это включает в себя добавление элементов, удаление элементов, извлечение их содержимого, их отображение и скрытие. Используйте встроенные директивы или, если необходимо, самостоятельно создайте свои собственные манипуляции с DOM. См. Ниже о дублирующих функциях.
Если вы пытаетесь нарушить привычку, подумайте об удалении jQuery из вашего приложения. В самом деле. Angular имеет службу $http и мощные директивы, которые делают ее почти всегда ненужной. Angular В комплекте jQLite есть несколько функций, наиболее часто используемых при написании директив Angular, особенно связанных с событиями.
Наконец, вот ваш пример, работающий с использованием этого метода: http://jsfiddle.net/BinaryMuse/xFULR/1/
Ответ 2
попробуйте $scope. $apply() внутри вашего контроллера после обновления вашей модели
Ответ 3
http://jsfiddle.net/zCC2c/
Ваша проблема двоякая.
1) В вашем jsfiddle произошла синтаксическая ошибка, так как DOMElements (например, возвращаемый значением $(this) внутри вашего кликера по щелчку не предотвращает дефолт. Фактически вам нужно передать событие. (Незначительная проблема синтаксиса).
2) Поместив определение переменной в область контроллеров следующим образом:
function MyCtrl($scope){
$scope.foo = foo;
}
Вы гарантируете, что он будет запущен один раз для создания экземпляра класса.
Что вы хотите:
function MyCtrl($scope){
$scope.someAngularClickHandler=function(){
$scope.foo = foo;
}
}
И затем по вашей ссылке
<a href="foo" id="bar" ng-click="someAngularClickHandler()">
Для более полного кода см. связанный jsfiddle.
Хороший обзор теории можно найти в первом разговоре здесь:
http://www.youtube.com/watch?feature=player_embedded&v=VxuN6WO3tIA
Ответ 4
В Angular приложениях модели обычно иногда реализуются в области $scope, а не как отдельный объект JavaScript. Ниже приведено описание вашего приложения, показывающее, как это сделать.
function myModelCtrl($scope) {
$scope.number = 0;
$scope.updateNumber = function () {
$scope.number += 1;
alert('new number should display ' + $scope.number);
}
}
HTML:
<div ng-controller="myModelCtrl">
<div>Number is {{number}}</div>
<a ng-click="updateNumber()">Update Number</a>
</div>
Здесь fiddle без jQuery, и он показывает "обычный способ" настройки скрипта для Angular.