简体   繁体   English

模型直接由View with Angular观看和调用 - 一个好主意?

[英]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-showng-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中。

Questions: 问题:

  1. Is my understanding of the issue correct? 我对这个问题的理解是否正确?
  2. Have I offended an Angular best practice with this approach? 我用这种方法冒犯了Angular最佳实践吗?
  3. Must I now do something like <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): 编辑 (回应戈登的回答):

  1. Is it a good idea to pass $scope or use $rootScope deep in the service, or should the service be Angular-agnostic? 传递$ scope或在服务中使用$ rootScope是一个好主意,还是该服务应该是Angular-agnostic? If not, what would be preferable? 如果不是,那会更好吗?

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.

相关问题 如果角度视图直接访问服务,这是一个好习惯吗? - If angular view accesses a service directly, is it a good practice? Angular JS + Rails好主意? - Angular js + Rails good idea? 尽管被观看,角度ui-router中的命名视图仍未更新 - Named view in angular ui-router not updating, despite being watched 将不同类型的模型放入主干集合中是一个好主意吗? - Is it a good idea to put different types of models in a backbone collection? 这是直接以角度更改构建文件的良好做法吗? - Is this good practice to change build files directly in angular? 在Angular Controller中立即调用函数,这是一个好习惯吗? - Immediately-Invoked Function inside of an Angular Controller, good practice? 正在监视的角度重新加载资源 - Angular reload resource that is being watched 如果直接调用,使用$ window.location.href在Angular中重定向有效,但如果从其他函数调用则无效 - Redirecting in Angular using $window.location.href works if invoked directly, but not if called from another function 过度收费是个好主意吗? - Is it a good idea to overcharge a method? 在迁移期间在同一个应用程序中同时使用Angular 1.x和2.0是一个好主意吗? - Is it a good idea to use both Angular 1.x and 2.0 in the same application during migration?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM