javascript - 具有嵌套范围的 Angular,尝试使用 $parent 但 watch 仍然没有更新

标签 javascript angularjs scope angularjs-scope

我有两个控件,一个 radio 控件和一个 list 控件,在任何给定时间只显示其中一个(基于 bool 多行)。

我也有一些逻辑观察$scope。这两个控件都位于同一个 Controller 内,因此它们共享相同的作用域。问题是,只有 radio 元素会触发 watch 语句!我一生都无法让愚蠢的 checklist 元素来处理它......但它应该,因为 campaignValues 肯定会使用新值进行更新!

我做错了什么?我已经在 .checkbox 类上尝试了多个 $parent 修饰符,但它们似乎没有做任何事情。 如何将 campaignValues 参数连接到 watchCollection 语句?

标记

<div class="radio" ng-repeat="campaign in campaigns" ng-if="!multiline">
  <input type="radio" name="name" 
         ng-model="$parent.$parent.campaignValue" 
         id="name_{{campaign}}" value="{{campaign}}"/>
  <label for="name_{{campaign}}">
    {{campaign}}
  </label>
</div>
<div class="checkbox" ng-repeat="campaign in campaigns" ng-if="multiline">
  <input type="checkbox" name="name" 
         ng-checked="campaignValues.indexOf(campaign) != -1" 
         ng-click="toggleCheck(campaign)" id="name_{{campaign}}" 
         value="{{campaign}}"/>
  <label for="name_{{campaign}}">
    {{campaign}}
  </label>
</div>

Controller

  // Initiate other module radio control
  // Hard-coded in - remember to change
  $scope.campaigns = ['A', 'B', 'C', 'D'];
  $scope.campaignValue = $scope.campaigns[0];

  // Initiate module checkbox control
  $scope.campaignValues = [];

  // Logic for handling when a checkbox is toggled
  $scope.toggleCheck = function(campaign) {
    if ($scope.campaignValues.indexOf(campaign) === -1) {
      $scope.campaignValues.push(campaign);
    } else {
      $scope.campaignValues.splice($scope.campaignValues.indexOf(campaign), 1)
    }
  };

$scope.$watchCollection(
  '[optionValue, campaignValue, campaignValues, multiline]', 
  function() {
    updateDashboard();
  });

最佳答案

如果您的模型是对象而不是基元,则不需要 $watchCollection。许多 Angulars 默认指令,例如 ng-bind 或 {{}},已经内置了 $watch 语句。如果您仅使用默认指令,并且您“点”了模型,则可以无需编写 $watch 语句即可构建应用程序。

我假设如果您调用 updateDashboard(),您的仪表板已标记有 {{}} 负载。

工作演示:http://plnkr.co/edit/AzhmeA?p=preview

注意:我删除了 ng-if,并添加了双重绑定(bind)以显示事件模型中的更改。

app.js

JS 中的两个更改,数组到对象,以及切片对象的路径。

// Changed array to object
$scope.campaigns = {obj: {data:['A', 'B', 'C', 'D']} };
// changed to object path
$scope.campaignValue = $scope.campaigns.obj.data[0];

// Initiate module checkbox control
$scope.campaignValues = [];

// Logic for handling when a checkbox is toggled
$scope.toggleCheck = function(campaign) {
    if ($scope.campaignValues.indexOf(campaign) === -1) {
        $scope.campaignValues.push(campaign);
    } else {
        $scope.campaignValues.splice($scope.campaignValues.indexOf(campaign), 1)
    }
};

HTML

HTML 中发生了三处更改,两个 ng-repeat 模型都更改为对象路径,并且删除了第二个 $parent 以获取 CampaignValue 模型更新。

// changed campaigns model to object path
<div class="radio" ng-repeat="campaign in campaigns.obj.data">

// dropped 2nd $parent to get double bindings working
<input type="radio" name="name" 
         ng-model="$parent.campaignValue"
         id="name_{{campaign}}" 
         value="{{campaign}}"/>

  <label for="name_{{campaign}}">
    {{campaign}}
  </label>

</div>

<br>
campaignValue:{{campaignValue}}
<br>
campaignValues:{{campaignValues}}
<br><br>

// changed campains model to object path
<div class="checkbox" ng-repeat="campaign in campaigns.obj.data">

  <input type="checkbox" name="name" 
         ng-checked="campaignValues.indexOf(campaigns) != -1" 
         ng-click="toggleCheck(campaign)" id="name_{{campaign}}" 
         value="{{campaign}}"/>

  <label for="name_{{campaign}}">
    {{campaign}}
  </label>

</div>

关于javascript - 具有嵌套范围的 Angular,尝试使用 $parent 但 watch 仍然没有更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24542675/

相关文章:

angularjs - 我如何从nodeJS触发Airflow Dag?

css - 在 Angular UI Grid 中设置选定行的背景颜色

c++ - BOOST_SCOPE_EXIT 将参数作为值传递

javascript - 在 Angular 中重构 $rootScope.$apply

javascript - 提交时在 Aurelia 中定位图像并保存在 JSON 类型数组中

javascript - Angular +传单+传单额外标记

javascript - Jquery ajax 函数停止工作

html - 在使用 angularjs 服务器端验证失败后,是否有办法恢复用户输入?

c++ - 限制头文件中 "using namespace"的范围

localization - Mathematica 中的词法和动态范围 : Local variables with Module, With 和 Block