【问题标题】:Access Angular scope of controller in nested partial在嵌套部分中访问控制器的角度范围
【发布时间】:2016-09-14 00:52:13
【问题描述】:

在我的 Angular 项目中,每个页面都有一个控制器。我包括一个在多个页面上使用的部分。在每个控制器中,我初始化一些值,然后在部分内部访问它们。

$scope.checkedItems = [];

在部分中我将数据绑定到它。

<input type="checkbox" checklist-model="$parent.$parent.$parent.$parent.$parent.checkedItems" checklist-value="item.Id">

部分是嵌套的,所以我必须多次使用 $parent 来访问控制器范围内的参数。这很丑陋。此外,部分包含在不同页面的不同位置,因此范围深度不一致。因此,在某些页面上,我需要上 5 级、8 级、4 级等。

有没有更简单的方法来访问控制器的范围?如果以下方法可行,那就太好了。

<input type="checkbox" checklist-model="$controllerScope.checkedItems" checklist-value="item.Id">

【问题讨论】:

    标签: angularjs


    【解决方案1】:

    为控制器之间的数据交换创建一项服务


    嵌套树选项

    在服务中创建一个具有父->子结构的对象,在嵌套模板中存储一些唯一的 id 来告诉服务在嵌套树中存储数据的位置

    在模板上下文中,它看起来很干净,但所有逻辑都将转移到服务中

    所以在模板中你会有类似的东西:

    <input type="checkbox" ng-checked="checked">
    

    在控制器中:

    $scope.uniqueid='3je99ehr0jer';//generate something...
    $scope.checked=false;
    yourService.set($scope.uniqueid,$scope.$parent.uniqueid,$scope.checked,function(checked){
      $scope.checked=checked;
    });
    //where first arg is controller unique id and second parent controller uniqueid
    $scope.$watch('checked',(...notify service to change data in tree...));
    

    当你想收集完整的树时,只需使用类似 yourService.getAll() 的东西

    树形结构应该是这样的:

    scope.dataTree={
      '3je99ehr0jer':{checked:true,children:[ another nodes that have parentid 3je99... ]}
    }
    

    添加/更改 dataTree 使用一些递归函数来查找您需要的 id

    yourService.set = function serviceSet(currentId,parentId,data,onChange){
      //find recursively parentId if not null
      // update value
      // notify parent node (or all) controllers that something has changed if you need (onChange argument)
    }
    

    平面对象选项

    如果您只想要带有 item.id->value 内容的平面对象,那么它会更简单,因为您可以在 yourService 中使用 dataTree 而不是这样的数据:

    scope.data= {
      '3je99ehr0jer':false,
      '03kefkeo0efe':true,
      ...
    }
    

    现在您不需要递归查找 id,只需要从 scope.data 对象 scope.data['3je99ehr0jer'] 获取您想要的内容


    我懒得测试这种方法,但你会弄清楚如何纠正一些问题,我不确定你是否需要通知 yourService $watch 方法发生了某些变化,如果 @987654329 yourService 中的 @ 方法也是需要的,但您会发现这一点,这个概念似乎是正确的 -> 基于唯一 ID 的数据交换服务

    如果您发现错误,请在评论中告诉我,以便我可以编辑此答案

    【讨论】:

    • 谢谢,但我最终使用了一个更简单的服务(工厂)。
    【解决方案2】:

    我最终创建了一个数据源作为工厂。

    工厂:

    define([], function () {
    
    'use strict';
    
    
    function checkedItemsDataSource(){
    
        var dataSource = {};
    
        dataSource.items = [];
    
        dataSource.setItems = function(items){
            dataSource.items = items;
        };
    
        return dataSource;
    
    }
    
    return checkedItemsDataSource;
    
    });
    

    控制器中,将选中的项目设置为一个空数组作为初始值。创建一个以工厂为值的变量。

    checkedItemsDataSource.setItems([]);
    $scope.checkedItemsDataSource = checkedItemsDataSource;
    

    当需要在任何其他控制器或嵌套范围内更改数据时,调用工厂的 setItems 函数。 $scope.checkedItemsDataSource 的值会自动更新。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多