使用具有相同控制器的多个模板更新 $scope

Updating $scope with multiple templates with same controller

我有以下路线:

.state('cloud', {
    url: '/cloud',
    views: { 
        'main': { templateUrl: 'pages/templates/cloud.html', controller: 'cloud' },
        'choices-header': { templateUrl: 'pages/templates/views/choices-header.html', controller: 'cloud' }
    }
})

我这样做是因为我需要 choices-header 模板进入与 main 模板不同的视图。

我的 choices-header 模板中的

#options_header 应该显示 $scope.cloud_selected_items 中是否有项目。

但由于某些原因,当一个项目被添加到数组中时,它并不知道这一点,所以该元素没有显示。但是,如果我使用数组中的项目重新加载页面,它将显示。所以我知道代码是 working.

有谁知道我需要对我的 cloudCheck() 函数做什么,以便范围 更新 和我的模板看到我的 $scope 中的变化?

所以在我的索引页中,我有:

<div ui-view="choices-header"></div>
<div id="pageContent">
    <div ui-view="main"></div>
</div>

cloud.html

<div ng-repeat="data in items">
   <div ng-click="cloudCheck(data.id)">Click me</div>
</div>

choices_header.html

<div id="option-header" ng-show="cloud_selected_items.length > 0">
    {{ cloud_selected_items.length }} selected
</div>

javascript

.controller('cloud', function($scope, $rootScope, $http, $state, $stateParams) {
    $scope.cloud_selected_items = [];

    $scope.cloudCheck = function(id) {
        $scope.cloud_selected_items.push(id);
    }
}

我认为您的代码的问题在于您的视图中没有共享范围。范围将在嵌套视图中继承,但您有两个单独的视图。

如果您这样做 console.log($scope),您会看到云控制器将 运行 两次,范围不同。可以看到作用域是不同的 属性 $id.

您可以使用跟踪所选项目的服务。然后 two-way 绑定将按预期更新您的 header 视图。

请查看下面的代码(此处无效,SO 上 ui-router 的 cookie 问题)和此处的工作演示 jsFiddle

angular.module('myApp', ['ui.router'])
    .controller('cloud', function ($scope, $state, cloudService) {
        $scope.items = [{
            id: 1,
            data: 'test1'
        },
        {
            id: 2,
            data: 'test2'
        },
        {
            id: 2,
            data: 'test2'
        }]; //dummy data
        $scope.cloud_selected_items = cloudService.getItems();
        
        $scope.cloudCheck = cloudService.cloudCheck;
        /*function(item) {
            console.log(id);
            $scope.cloud_selected_items.push(item);
        };*/
})
.factory('cloudService', function() {
    var cloudSelectedItems = [];
    
    var cloudService = {
        cloudCheck: function(item) {
            cloudSelectedItems.push(item);
        },
        getItems: function() {
            return cloudSelectedItems;
        }
    };
    
    return cloudService;
})
.config(function ($stateProvider, $urlRouterProvider) {
    //
    // For any unmatched url, redirect to /state1
    $urlRouterProvider.otherwise("/cloud");
    //
    // Now set up the states
    $stateProvider.state('cloud', {
        url: '/cloud',
        views: { 
            'main': {
                templateUrl: 'partials/cloud.html', controller: 'cloud' 
            },
            'choicesheader': { 
                templateUrl: 'partials/choices_header.html', 
                controller: 'cloud' 
            }
        }
    });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.14/angular-ui-router.min.js"></script>

<script type="text/ng-template" id="partials/choices_header.html">
    <div id="option-header" ng-show="cloud_selected_items.length > 0">
    {{ cloud_selected_items.length }} selected
</div>
</script>

<script type="text/ng-template" id="partials/cloud.html">
    <div ng-repeat="data in items">
        <button ng-click="cloudCheck(data.id)">Click me</button>
    </div>
</script>

<div ng-app="myApp">
  <div ui-view="choicesheader"></div>
  <div id="pageContent">
    <div ui-view="main"></div>
  </div>
</div>