我试图获得一个带有共享对象实例的指令来更新该实例,然后看到其他地方反映的更改。
下面,我简化并简化了我的代码,解释了设置,没有讨论各种不相关的细节。
请注意,在我们的实际代码中,Commitment
是一个复杂的模型"具有许多业务逻辑和附加属性。并且Service
(以及更少的指令)做得更多(例如处理错误,发送弹出通知,进行客户端验证等)。因此,请理解我并不是为了使其变得复杂而使其变得复杂。我们确实需要所有这些层,即使我理解复杂性本身就是问题的根源。
另请注意,代码可能不再有效:删除所有不相关的部分并缩小代码后可能会出现拼写错误。
以下代码的问题在于,首先payments
和credit
两个都绑定得很好。更新一个使另一个跟随。
但是,从那时起,进行第二次更新时,angular仅更改触发实际更新的更新:似乎在第一次更新后,payments
不再指向彼此,而是分离或运行他们自己的范围或一些这样的。这就是我想要解决的问题:将它们捆绑在一起。
我有一个指令commitment
。这会传入对象。每个视图使用承诺多次,在这种情况下,它会传入相同的对象。简化:
<commitment commitment="payment"></commitment>
<commitment commitment="credit"></commitment>
<hr/>
<commitment commitment="payment"></commitment>
<commitment commitment="credit"></commitment>
payment
和credit
来自某些uiRouter,大致实例化为:
$scope.payment = CommitmentService.buildCommitment();
$scope.credit = CommitmentService.buildCommitment();
所以,现在我们有两个对象,分离和解耦。一个payment
和一个credit
。但两者都使用了两次:例如,我们看到payment
两次。因此,两个指令使用相同的payment
对象实例。
在指令中,可以通过与后端的某些API交互来更新。在我们的代码中,这将通过服务层进行。再次,简化,首先是模板:
<a href="" ng-click="toggleState()">it is: {{ commitment.state }}</a>
指令:
var app = angular.module('app');
app.directive('commitment', function () {
return {
templateUrl: 'app/views/partials/commitment.html',
restrict: 'E',
scope: {
commitment: '='
},
link: function ($scope, $element) {
$scope.toggleState = function () {
CommitmentService.update($scope.commitment, { state: "paid" },
function (commitment) { // success
$scope.commitment = commitment;
},
function (error) { // error
console.log("error: " + error);
}
);
}; // toggleState()
} // controller
};
}]);
服务的相关部分:
var app = angular.module("app");
app.service('CommitmentService', ['$http', function ($http) {
this.update = function (commitment, attributes, successMethod, errorMethod) {
var payload = { commitment: attributes };
$http.patch(commitment.urls().update, payload).then(
function (response) { // On Success
if (successMethod) { successMethod(new Commitment(response.data)); }
},
function (response) { // On Error
if (errorMethod) { errorMethod(response.data); }
}
);//patch.then
}// this.update
this.buildCommitment() {
return new Commitment({state: "not paid", amount: 1337 });
}
function Commitment(attributes) {
this.state = attributes.state;
this.amount = attributes.amount;
this.urls = function() {
{ update: attributes.update_link }
};
}
}