我遇到了一个问题(我想我能理解),但我不清楚解决方案是什么。
简而言之,我有一个BackendService
,它封装了一些非Angular对象模型(在我的例子中是SharePoint,但这与重点无关)。我创建了这个BackendService
,这样它就可以返回Angular兼容的实体(items
),这样我就可以做如下操作:
angular.module("app", [])
.factory("BackendService", function(){
return new BackendService();
})
.controller("MainCtrl", function($scope, BackendService){
BackendService.GetItems()
.then(function(items){
$scope.Items = items;
$scope.$apply();
});
});
到目前为止还不错。
除了,我希望每个item
都是一个自给自足的ViewModel-y,这样它就可以直接在视图中使用。换句话说,我想做以下操作(注意按钮的ng-show
和ng-click
):
<div ng-controller="MainCtrl">
<div ng-repeat="item in Items">
<input ng-model="item.fieldA" type="text"/>
<input ng-model="item.fieldB" type="text"/>
<button ng-show="item.IsDirty()" ng-click="item.Save()">Save</button>
</div>
</div>
当有任何更改(设置脏标志)时,按钮会立即显示,但当item.Save()
(async函数)在脏标志未设置的地方被调用时,更改在DOM中不可见。
所以问题是:item.IsDirty() === false
时按钮不会隐藏。
我的理解是,item.Save()
是一个异步函数,它使用的对象模型在背后使用Ajax(它不使用$http,因为它不知道Angular),因此绕过了摘要循环。因此,item.IsDirty()
中的更改永远不会反映在DOM中。
问题:
- 我对这个问题的理解正确吗
- 这种方法是否冒犯了Angular的最佳实践
- 我现在必须做点什么吗比如
<button ng-click="SaveItem(item)">
,并在其中调用$scope.$apply
编辑(针对Gordon的回答):
- 在服务,或者服务应该是角度不可知的?如果没有,什么更可取
谢谢!
问题是您的scope.items数组没有绑定到服务中的任何数据。我会通过在您的服务中的对象上设置一个items属性来解决这个问题,该属性是绑定到您的scope items属性的数据。
BackendService.loadData()
.then(function() {
$scope.data = BackendService.data;
});
// data is an object with a property items
然后,就在服务中的数据发生更改时,更新本地项数组,它们将被角度数据绑定跟踪。
啊,我终于明白了。我可以用发射来触发应用程序来绕过它:http://plnkr.co/edit/F8rLK2?p=preview
请参阅此问答;鹿的A:angularjs ng显示与承诺表达式