【问题标题】:Angular with nested scopes, tried using $parent but watch still not updating具有嵌套作用域的 Angular,尝试使用 $parent 但观察仍然没有更新
【发布时间】:2014-08-23 22:14:10
【问题描述】:

我有两个控件,一个无线电控件和一个清单控件,在任何给定时间只显示其中一个(基于布尔值 multiline)。

我也有一些逻辑看$scope。这两个控件都在同一个控制器内,因此它们共享相同的范围。问题是,只有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>

控制器

  // 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();
  });

【问题讨论】:

  • 试图将原语传递到子范围的经典问题...始终使用对象。或者,换句话说......ng-model 应该总是有一个dot
  • 哦,我想我现在明白了。我看看能不能解决。
  • 我实际上认为您可能读错了我的问题。我没有遇到无线电模块问题,而是复选框一。我按照您的说明进行操作,虽然我的代码更好,但并没有解决问题。

标签: javascript angularjs scope angularjs-scope


【解决方案1】:

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

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

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

注意:我已删除 ng-if,并添加了双重绑定以显示活动模型中的更改。

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 被删除以获取活动值模型更新。

// 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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-11-09
    • 1970-01-01
    • 2019-02-19
    • 1970-01-01
    • 1970-01-01
    • 2018-12-23
    • 1970-01-01
    相关资源
    最近更新 更多