angularjs 范围值更新时指令不更新
angularjs directive doesn't update when scope value update
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.min.js"></script>
<script type="text/javascript">
(function(){
'use strict';
angular.module('myApp',[])
.controller('TestCtrl',TestCtrl)
.directive('trxTablePersonTd',trxTablePersonTd);
function TestCtrl($scope){
var vm = $scope.vm = this;
vm.trxs = [
{id:"1",acctKey:"2",persons:[{name:'peter',age:20},{name:'hank',age:23}]},
{id:"2",acctKey:"3",persons:[{name:'Joe'},{name:'Jason'}]}
];
$scope.changePerson = function(){
vm.trxs[1]['persons']['age'] = 33;
vm.trxs[1]['acctKey'] = 123;
}
}
function trxTablePersonTd($compile){
return{
scope:{persons:'=persons'},
restrict:'A',
link:link,
replace:false,
//compile:compile
}
function compile(elem,attrs){
return function(scope){
var html = [];
scope.persons.map(function(person,index){
html.push('<td>'+person.name+'</td>');
html.push('<td>'+person.age+'</td>');
});
}
}
function link(scope, elem, attrs){
var html = [];
if(scope.persons){
scope.persons.map(function(person,index){
html.push('<td>'+person.name+'</td>');
html.push('<td>'+person.age+'</td>');
});
}
elem.replaceWith(html.join(''));
$compile(elem.contents())(scope);
}
}
}());
</script>
</head>
<body ng-app="myApp" ng-controller="TestCtrl">
<button type="button" name="button" ng-click="changePerson()">change person</button>
<table border="1">
<tbody>
<tr ng-repeat="trx in vm.trxs">
<td>
{{trx.id}}
</td>
<td>
{{trx.acctKey}}
</td>
<td trx-table-person-td persons="trx.persons">
</td>
</tr>
</tbody>
</table>
</body>
</html>
Blockquote
当我点击按钮时,未定义的年龄没有得到更新。谁能帮我看看这个问题
当我点击按钮时,未定义的年龄没有得到更新。谁能帮我看看这个问题
我一直在等着看是否有人会比我更好、更权威地回答这个问题。我认为问题是因为范围更新没有像您的更改那样深入到数据结构中。我认为您需要在 vm.trxs
上实施深度监视 ("watch by value")。请参阅 https://docs.angularjs.org/guide/scope,向下滚动到 "Controllers and Scopes" 部分。
您没有在 $scope.changePerson
方法中正确更新 collection。 persons
也是一个数组,应该像
$scope.changePerson = function () {
vm.trxs[0]['persons'][0]['age'] = 33; //look ['persons'][0]
vm.trxs[0]['acctKey'] = 123;
}
正如@Ed Staub 建议的那样,您需要 $watch
您的 collection 来传播进一步的模型更改,例如
app.directive('trxTablePersonTd', function ($compile) {
return {
scope: { persons: '=persons' },
restrict: 'A',
link: link,
replace: false,
}
function link(scope, elem, attrs) {
if (scope.persons) {
scope.$watch('persons', function () {
var html = scope.persons.map(function (person, index) {
return '<td>' + person.name + '</td>' + '<td>' + (person.age ? person.age : "") + '</td>';
});
elem.empty().append(html.join(''));
$compile(elem.contents())(scope);
}, true);
}
}
});
此外,如果您的指令中除了 td
之外没有其他 html
,我认为您根本不需要指令,只需使用 ng-repeat
喜欢
<td ng-repeat="person in trx.persons">
<span>{{person.name}}</span>
<span>{{person.age}}</span>
</td>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.min.js"></script>
<script type="text/javascript">
(function(){
'use strict';
angular.module('myApp',[])
.controller('TestCtrl',TestCtrl)
.directive('trxTablePersonTd',trxTablePersonTd);
function TestCtrl($scope){
var vm = $scope.vm = this;
vm.trxs = [
{id:"1",acctKey:"2",persons:[{name:'peter',age:20},{name:'hank',age:23}]},
{id:"2",acctKey:"3",persons:[{name:'Joe'},{name:'Jason'}]}
];
$scope.changePerson = function(){
vm.trxs[1]['persons']['age'] = 33;
vm.trxs[1]['acctKey'] = 123;
}
}
function trxTablePersonTd($compile){
return{
scope:{persons:'=persons'},
restrict:'A',
link:link,
replace:false,
//compile:compile
}
function compile(elem,attrs){
return function(scope){
var html = [];
scope.persons.map(function(person,index){
html.push('<td>'+person.name+'</td>');
html.push('<td>'+person.age+'</td>');
});
}
}
function link(scope, elem, attrs){
var html = [];
if(scope.persons){
scope.persons.map(function(person,index){
html.push('<td>'+person.name+'</td>');
html.push('<td>'+person.age+'</td>');
});
}
elem.replaceWith(html.join(''));
$compile(elem.contents())(scope);
}
}
}());
</script>
</head>
<body ng-app="myApp" ng-controller="TestCtrl">
<button type="button" name="button" ng-click="changePerson()">change person</button>
<table border="1">
<tbody>
<tr ng-repeat="trx in vm.trxs">
<td>
{{trx.id}}
</td>
<td>
{{trx.acctKey}}
</td>
<td trx-table-person-td persons="trx.persons">
</td>
</tr>
</tbody>
</table>
</body>
</html>
Blockquote
当我点击按钮时,未定义的年龄没有得到更新。谁能帮我看看这个问题
当我点击按钮时,未定义的年龄没有得到更新。谁能帮我看看这个问题
我一直在等着看是否有人会比我更好、更权威地回答这个问题。我认为问题是因为范围更新没有像您的更改那样深入到数据结构中。我认为您需要在 vm.trxs
上实施深度监视 ("watch by value")。请参阅 https://docs.angularjs.org/guide/scope,向下滚动到 "Controllers and Scopes" 部分。
您没有在 $scope.changePerson
方法中正确更新 collection。 persons
也是一个数组,应该像
$scope.changePerson = function () {
vm.trxs[0]['persons'][0]['age'] = 33; //look ['persons'][0]
vm.trxs[0]['acctKey'] = 123;
}
正如@Ed Staub 建议的那样,您需要 $watch
您的 collection 来传播进一步的模型更改,例如
app.directive('trxTablePersonTd', function ($compile) {
return {
scope: { persons: '=persons' },
restrict: 'A',
link: link,
replace: false,
}
function link(scope, elem, attrs) {
if (scope.persons) {
scope.$watch('persons', function () {
var html = scope.persons.map(function (person, index) {
return '<td>' + person.name + '</td>' + '<td>' + (person.age ? person.age : "") + '</td>';
});
elem.empty().append(html.join(''));
$compile(elem.contents())(scope);
}, true);
}
}
});
此外,如果您的指令中除了 td
之外没有其他 html
,我认为您根本不需要指令,只需使用 ng-repeat
喜欢
<td ng-repeat="person in trx.persons">
<span>{{person.name}}</span>
<span>{{person.age}}</span>
</td>