[英]Models directly $watched and invoked by the View with Angular - a good idea?
I ran into a problem (which I think I understand), but I'm not clear about what the solution could be. 我遇到了一个问题(我认为我理解),但我不清楚解决方案是什么。
In a nutshell, I have a BackendService
that wraps some non-Angular object model (in my case, SharePoint, but that is beside the point). 简而言之,我有一个BackendService
包装了一些非Angular对象模型(在我的例子中,SharePoint,但这不是重点)。 I created this BackendService
so that it could return Angular-compatible entities ( items
), so that I could do something like the following: 我创建了这个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();
});
});
So far so good. 到现在为止还挺好。
Except, I wanted each item
to be a self-sufficient and ViewModel-y such that it could be used directly in the View. 除此之外,我希望每个item
都是自给自足的ViewModel-y,以便它可以直接在View中使用。 In other words, I wanted to do the following (notice the button's ng-show
and ng-click
): 换句话说,我想要执行以下操作(请注意按钮的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>
The button shows immediately when there is any change (which sets the dirty flag), but when item.Save()
- an async function - is called where the dirty flag is unset, the change is not visible in the DOM. 当有任何更改(设置脏标志)时,按钮立即显示,但是当item.Save()
- 异步函数 - 未设置脏标志时,更改在DOM中不可见。
So the problem is : the button doesn't hide when item.IsDirty() === false
. 所以问题是 :当item.IsDirty() === false
时,按钮不会隐藏。
My understanding is that item.Save()
being an async function that uses the object model which uses Ajax under the covers (which doesn't use $http since it's not aware of Angular) thus bypasses the digest loop. 我的理解是item.Save()
是一个异步函数,它使用在封面下使用Ajax的对象模型(由于它不知道Angular而不使用$ http)因此绕过了摘要循环。 Because of this, the change in item.IsDirty()
is never reflected in the DOM. 因此, item.IsDirty()
的更改永远不会反映在DOM中。
<button ng-click="SaveItem(item)">
and call $scope.$apply
within it? 我现在必须做一些像<button ng-click="SaveItem(item)">
并调用$scope.$apply
吗? Edit (in response to an answer by Gordon): 编辑 (回应戈登的回答):
Thanks! 谢谢!
The problem is your scope.items array isn't bound to any data from your service. 问题是您的scope.items数组未绑定到您的服务中的任何数据。 I'd solve this problem by having an items property on ain object in your service that is data bound to your scope items property. 我通过在服务中的ain对象上设置items属性来解决此问题,该对象是绑定到scope项属性的数据。
BackendService.loadData()
.then(function() {
$scope.data = BackendService.data;
});
// data is an object with a property items
Then just as changes happen to the data in your service update the local items array and they will be tracked by the angular data binding. 然后,当服务中的数据发生更改时,更新本地项目数组,它们将由角度数据绑定进行跟踪。
Ah I finally get it. 啊,我终于明白了。 I was able to get it around it using an emit to trigger an apply: http://plnkr.co/edit/F8rLK2?p=preview 我能够使用emit触发一个应用程序来解决它: http : //plnkr.co/edit/F8rLK2?p = preview
See this Q&A for the deets: angularjs ng-show with promise expression 请参阅此问答的deets: angularjs ng-show with promise expression
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.