<div class="btn-group" role="group" aria-label="...">
<label ng-repeat="year in years" ng-class="{'btn-primary': year === selectedYear}" class="btn btn-default">
<input type="radio" ng-model="$parent.selectedYear" name="year" ng-value="year" />
{{year}}
</label>
</div>
在这段代码中,我理解我需要使用$parent
绑定到$scope.selectedYear
,因为ngRepeat创建了自己的范围,而selectedYear
是属于父范围的原语。 / p>
我不明白ng-class="{'btn-primary': year === selectedYear}
的工作原理。
ngRepeat范围内的ngClass是什么?如果是这样,为什么selectedYear
不需要$parent
,如果不是,它如何使用ngRepeat范围内的year
?
angular.module("app", [])
.controller("controller", function($scope) {
$scope.currentYear = new Date().getFullYear();
$scope.selectedYear = $scope.currentYear;
$scope.years = [$scope.currentYear - 1, $scope.currentYear, $scope.currentYear + 1];
});
&#13;
body > div {
padding: 15px;
}
.btn-group > label > input[type="radio"] {
display: none;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<div ng-app="app" ng-controller="controller">
<div class="btn-group" role="group" aria-label="...">
<label ng-repeat="year in years" class="btn btn-default" ng-class="{'btn-primary': year === selectedYear}">
<input type="radio" ng-model="$parent.selectedYear" name="year" ng-value="year" />
{{year}}
</label>
</div>
<br/>
<br/>
Selected year: {{selectedYear}}
</div>
&#13;
答案 0 :(得分:2)
您也可以在没有$ parent引用的情况下执行此操作。问题在于范围继承。创建子作用域时,所有变量(对象和基本变量)都在子作用域中,其名称与父作用域中的名称相同。但是当您更改子范围内的原始变量时,它们仅在子范围内更改
互联网上有很多关于范围继承的信息。例如,有一个很好的解释:https://github.com/angular/angular.js/wiki/Understanding-Scopes
你可以做些什么来避免这种情况 - 总是把你想要绑定的原始变量放在对象中(比如我下面的代码片段)
关于您的问题 -
ngRepeat范围内的ngClass是
我认为,ngClass创建了自己的范围。此范围继承父范围的变量(ngRepeat的范围和控制器的范围)。因此,原始变量selectedYear在ng-repeat的范围和ng-class范围内是不一样的。不正确,请参阅注释
angular.module("app", [])
.controller("controller", function($scope) {
$scope.settings = {currentYear: new Date().getFullYear()};
$scope.settings.selectedYear = $scope.settings.currentYear;
$scope.settings.years = [$scope.settings.currentYear - 1, $scope.settings.currentYear, $scope.settings.currentYear + 1];
});
&#13;
body > div {
padding: 15px;
}
.btn-group > label > input[type="radio"] {
display: none;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<div ng-app="app" ng-controller="controller">
<div class="btn-group" role="group" aria-label="...">
<label ng-repeat="year in settings.years" class="btn btn-default" ng-class="{'btn-primary': year === settings.selectedYear}">
<input type="radio" ng-model="settings.selectedYear" name="year" ng-value="year" />
{{year}}
</label>
</div>
<br/>
<br/>
Selected year: {{settings.selectedYear}}
</div>
&#13;
答案 1 :(得分:1)
回答第一个问题
Is the ngClass inside the ngRepeat's scope?
由于ng-repeat和ng-class存在于同一元素上,因此执行顺序由每个指令的priority
决定。 ng-repeat的优先级为1000,ng-class的优先级为0,这意味着理想的执行顺序应为
1) Compile of ng-repeat
2) compile of ng-class
3) link of ng-repeat
4) link of ng-class
根据我的理解,因为ng-class首先被链接(附加范围),所以你不必使用$parent.selectedYear
。
我可能错了,但这是我的理解。希望它可能会有所帮助。
修改强>
阅读ng-class和ng-repeat代码后。需要添加一些更正/更改
首先,ng-class和ng-repeat都不会创建孤立的范围。
其次,我提到的执行顺序并不准确。订单应该是
1) compile of ng-repeat
2) link of ng-repeat
3) link of ng-class (ng-class doesn't have compile)
这是因为ng-repeat在其链接函数中使用$ watchCollection,它使用setTimeout
更新范围异步。
现在在ng-repeat的链接阶段,它循环遍历数组并使用transclude函数将范围附加到模板(在这种情况下,这是整个div与ng-repeat。) 这意味着,所有重复的元素都将具有遵循原型层次结构的新范围。这意味着您可以在子范围内(ng-repeat的范围)访问附加到范围的属性(在本例中,是控制器中作用域的属性)。
由于ng-class再次没有隔离范围且内部没有创建新范围,因此ng-class中的范围应与ng-repeat中使用的范围相同。
非常感谢任何建议/修改,因为我不是专业人士。
如果你能安装一个工作的掠夺者,那就太棒了。
回答如何在ng-class中使用年份?。如果year
表示用户在文本框中输入的值,则可以按照您使用它的方式使用它,它应该可以正常工作。
答案 2 :(得分:1)
由于范围原型继承,您可以从父范围读取没有$ parent的值。
对于ng-model,您必须使用$parent
直接引用父作用域,因为ng-model
使用双向绑定 - 否则新值将设置为子作用域而不是父作用域,因为selectedYear是原始的。