AngularJS:如何在指令作用域的对象发生变化时更新关联的控制器作用域?
AngularJS : How to update controller scope associated to directive scope's object as it changes?
解释如下:
我有当前控制器创建一个 $scope.plan.steps 的数组,它将用于存储每个步骤:
.controller('PlanCtrl', function ($scope, $http) {
$scope.plan = {
steps: [{}]
};
$scope.addStep = function () {
$scope.tutorial.steps.push({});
}
}
然后我有以下指令,它有一个独立的范围,并且关联到 $scope.plan.steps 数组的索引:
.directive('planStep', function () {
return {
template: '<input type="text" ng-model="step.name" />{{step}}',
restrict: 'E',
scope: {
index: '=index'
},
transclude: true,
controller: function($scope, $element, $transclude) {
$scope.removeStep = function() {
$scope.$emit('removeStep', $scope.index);
$element.remove();
$scope.$destroy();
}
}
};
});
这两个在控制器范围内进行通信、创建和删除对象,但是,如何让指令实时更新控制器的范围数组?
我已经尝试对指令的独立范围更改执行 $watch,将更改 $emit 到控制器,并指定 $index...但没有成功。
我创建了一个 plunker 来重现我目前拥有的内容:
Link
到目前为止,我可以在数组中创建和删除对象,但我无法获取单个对象来根据 $index 更新控制器的对象。
如果解释不清楚,一定要告诉我,我会详细说明。
谢谢
您为索引设置 2 向绑定的方式是否也可以为 step
设置一个?你真的不需要索引来删除项目,尽管你的指令是孤立的,它依赖于 ng-repeat 的索引,这可能不是一个好主意。
<plan-step ng-repeat="step in plan.steps" index="$index" step="step"></plan-step>
并在您的指令中:
scope: {
index: '=index',
step:'='
},
去除$index依赖和冗余元素remove()和scope destroy(当元素从数组中移除时angular会自行管理):
return {
template: '<button ng-click="removeStep()">Delete step</button><br><input type="text" ng-model="step.name" />{{step}}<br><br>',
restrict: 'E',
scope: {
step:'='
},
transclude: true,
controller: function($scope, $element, $transclude) {
$scope.removeStep = function() {
$scope.$emit('removeStep', $scope.step);
}
}
在你的控制器中:
$scope.$on('removeStep', function(event, data) {
var steps = $scope.plan.steps;
steps.splice(steps.indexOf(data), 1);
});
如果您想摆脱 $emit,您甚至可以使用带有函数绑定 (&) 的独立作用域指令公开一个 api。
return {
template: '<button ng-click="onDelete({step:step})">Delete step</button><br><input type="text" ng-model="step.name" />{{step}}<br><br>',
restrict: 'E',
scope: {
step:'=',
onDelete:'&' //Set up function binding
},
transclude: true
};
并将其注册到视图中:
<plan-step ng-repeat="step in plan.steps" step="step" on-delete="removeStep(step)"></plan-step>
当你在 ng-repeat
中做这样的事情时,你可以利用 ng-repeat 创建的子作用域并在没有隔离作用域的情况下工作。
这是相同的指令,不需要任何 angular 事件
.directive('planStep', function() {
return {
template: '<button ng-click="removeStep(step)">Delete step</button><br><input type="text" ng-model="step.name" />{{step}}<br><br>',
restrict: 'E',
transclude: true,
controller: function($scope, $element, $transclude) {
var steps = $scope.plan.steps// in scope from main controller
/* can do the splicing here if we want*/
$scope.removeStep = function(step) {
var idx =steps.indexOf(step)
steps.splice(idx, 1);
}
}
};
});
另请注意,使用 element.remove() 删除元素是多余的,因为它会在拼接数组时被 angular 自动删除
关于更新,会实时更新商品
解释如下:
我有当前控制器创建一个 $scope.plan.steps 的数组,它将用于存储每个步骤:
.controller('PlanCtrl', function ($scope, $http) {
$scope.plan = {
steps: [{}]
};
$scope.addStep = function () {
$scope.tutorial.steps.push({});
}
}
然后我有以下指令,它有一个独立的范围,并且关联到 $scope.plan.steps 数组的索引:
.directive('planStep', function () {
return {
template: '<input type="text" ng-model="step.name" />{{step}}',
restrict: 'E',
scope: {
index: '=index'
},
transclude: true,
controller: function($scope, $element, $transclude) {
$scope.removeStep = function() {
$scope.$emit('removeStep', $scope.index);
$element.remove();
$scope.$destroy();
}
}
};
});
这两个在控制器范围内进行通信、创建和删除对象,但是,如何让指令实时更新控制器的范围数组?
我已经尝试对指令的独立范围更改执行 $watch,将更改 $emit 到控制器,并指定 $index...但没有成功。
我创建了一个 plunker 来重现我目前拥有的内容:
Link
到目前为止,我可以在数组中创建和删除对象,但我无法获取单个对象来根据 $index 更新控制器的对象。
如果解释不清楚,一定要告诉我,我会详细说明。
谢谢
您为索引设置 2 向绑定的方式是否也可以为 step
设置一个?你真的不需要索引来删除项目,尽管你的指令是孤立的,它依赖于 ng-repeat 的索引,这可能不是一个好主意。
<plan-step ng-repeat="step in plan.steps" index="$index" step="step"></plan-step>
并在您的指令中:
scope: {
index: '=index',
step:'='
},
去除$index依赖和冗余元素remove()和scope destroy(当元素从数组中移除时angular会自行管理):
return {
template: '<button ng-click="removeStep()">Delete step</button><br><input type="text" ng-model="step.name" />{{step}}<br><br>',
restrict: 'E',
scope: {
step:'='
},
transclude: true,
controller: function($scope, $element, $transclude) {
$scope.removeStep = function() {
$scope.$emit('removeStep', $scope.step);
}
}
在你的控制器中:
$scope.$on('removeStep', function(event, data) {
var steps = $scope.plan.steps;
steps.splice(steps.indexOf(data), 1);
});
如果您想摆脱 $emit,您甚至可以使用带有函数绑定 (&) 的独立作用域指令公开一个 api。
return {
template: '<button ng-click="onDelete({step:step})">Delete step</button><br><input type="text" ng-model="step.name" />{{step}}<br><br>',
restrict: 'E',
scope: {
step:'=',
onDelete:'&' //Set up function binding
},
transclude: true
};
并将其注册到视图中:
<plan-step ng-repeat="step in plan.steps" step="step" on-delete="removeStep(step)"></plan-step>
当你在 ng-repeat
中做这样的事情时,你可以利用 ng-repeat 创建的子作用域并在没有隔离作用域的情况下工作。
这是相同的指令,不需要任何 angular 事件
.directive('planStep', function() {
return {
template: '<button ng-click="removeStep(step)">Delete step</button><br><input type="text" ng-model="step.name" />{{step}}<br><br>',
restrict: 'E',
transclude: true,
controller: function($scope, $element, $transclude) {
var steps = $scope.plan.steps// in scope from main controller
/* can do the splicing here if we want*/
$scope.removeStep = function(step) {
var idx =steps.indexOf(step)
steps.splice(idx, 1);
}
}
};
});
另请注意,使用 element.remove() 删除元素是多余的,因为它会在拼接数组时被 angular 自动删除
关于更新,会实时更新商品