2013-01-17 133 views
7

我已阅读此主题,例如:The view is not updated in 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

这里没有足够的代码来准确地告诉你什么是错的。你能向我们展示一个导致模型更新的交互的例子,但不是视图?如果你有一个关于jsFiddle或类似的例子,那就更好了。 –

+0

如果你可能会从视图代码中发布一段摘录,展示它如何与Controller进行交互,以及它期望myModel的位置,那就太棒了。如果你可以在一定程度上充实MyModel函数,那也很有帮助。正如布兰登上面所说的那样,你所拥有的并不足以让你知道发生了什么。 –

+0

@BrandonTilley,我加了的jsfiddle例如:http://jsfiddle.net/DAk8r/1/ – Alon

回答

9

你的问题的关键是,你试图用一个非常传统的混合AngularJS,“jQuery-汤风格“的JavaScript模式。在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如何,我们使用角度的内置ng-click指令。这使我们能够配合Angular范围生命周期,并在用户单击链接时正确更新视图。

下面是来自AngularJS FAQ报价;我粗体显示了一部分可能会帮助你打破习惯的部分。

常见缺陷

的角支撑通道(Freenode上#angularjs)看到许多重复的缺陷在于角落入的新用户。这份文件旨在在你发现困难之前指出它们。

DOM操作

停止尝试使用jQuery修改DOM的控制器。真。这包括添加元素,删除元素,检索其内容,显示和隐藏它们。使用内置指令,或者在必要时编写自己的指令,以执行DOM操作。请参阅下面的重复功能。

如果你正在努力打破这个习惯,可以考虑从应用中删除的jQuery。真。 Angular拥有$ http服务和强大的指令,这使得它几乎总是不必要的。 Angular捆绑的jQLite具有一些写作Angular指令最常用的特性,特别是绑定到事件。

最后,在这里你的榜样,使用这种技术的工作:http://jsfiddle.net/BinaryMuse/xFULR/1/

+0

为什么你需要'var _this = this;'? – Alex78191

9

试控制器在$范围。$适用()后,您更新模型

+1

在我的控制器$ scope中没有被玷污,你可以在jsfiddle.net/DAk8r/2中看到 – Alon

+0

这很好。但是,请你解释为什么需要它。它应该默认反映为角度承诺[双向数据绑定](https://docs.angularjs.org/tutorial/step_04) – Sami

1

http://jsfiddle.net/zCC2c/

你的问题是双重的。

1)在jsfiddle中有一个语法错误,因为DOMElements(比如点击处理程序中的$(this)返回的a没有阻止默认设置),您实际上需要传递一个事件(小的语法问题)。

2)通过将控制器范围内的变量定义,像这样:

function MyCtrl($scope){ 
    $scope.foo = foo; 
} 

你保证它得到每类实例化运行一次。

你想要的是:

function MyCtrl($scope){ 
     $scope.someAngularClickHandler=function(){ 
     $scope.foo = foo; 
     } 
} 

然后你的链接

<a href="foo" id="bar" ng-click="someAngularClickHandler()"> 

,了解更详尽的codesample查看链接的jsfiddle。

理论的一个很好的概述,可以在这里先说说发现:

http://www.youtube.com/watch?feature=player_embedded&v=VxuN6WO3tIA

+2

控制器不是单身人士。您可以在同一页面多次实例化MyCtrl。也许你对控制器的服务感到困惑 - 服务是单身人士。 –

0

在角的应用程序,模型通常 有时 在$范围实施,而不是作为一个独立的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的,它显示了建立捣鼓的“正常方式”角。

+2

AngularJS最佳做法经常被援引的是[“范围不是你的模型。适用范围是什么,你重视你的模型。”(http://youtu.be/ZhfUv0spHCY?t=30m)对于非常简单的控制器,这种事情可能会好起来,但通常你会想拥有自己的模型层。 –

+0

@Brandon,感谢您的视频链接(我还没有看到那个)。我感觉我现在明白了[Scope](http://docs.angularjs。org/guide/scope)页面:“范围是_refers_到应用程序模型的对象。”你认为服务是定义模型层的一种方式吗?如果不是,你建议在哪里定义模型?您是否知道有具有单独模型图层的Angular应用程序的任何良好示例? –

+1

供其他读者参考,在与布兰登的其他评论交流中,我想他会说服务是定义模型的地方。例如,请参阅Brandon的[这个答案](http://stackoverflow.com/a/14667066/215945)。 –

相关问题