在控制器之间共享模型数据

时间:2015-09-20 21:04:13

标签: html angularjs angularjs-directive angularjs-scope single-page-application

警告:详细描述我实际在做什么。

我有一个单页应用程序,其布局如下:

enter image description here

正如您所看到的,它是由标签组成的布局,每个标签都是一个带有它自己的控制器(和范围)的指令。所有形式它都是一个指令本身,由小指令组成,包含在标签中,如下所示:

main.html中

<div class="container-fluid">
  <div class="evaCont">
    <div class="eva_title">Form</div>
    <form id="mainForm" ng-submit="submit()">
      <div class="col-xs-12">
        <input type="submit" class="btn btn-primary" value="Save"/>
      </div>

      <div class="tab col-xs-12">
        <tabset justified="true">
          <tab heading="Data section 1">
            <ds1></ds1>
          </tab>
          <tab heading="Data section 2">
            <ds2></ds2>
          </tab>
          <tab heading="...">
            <ds3></ds3>
          </tab>
        </tabset>
      </div>
    </form>
  </div>
</div>

要使用数据填充SPA,请调用REST API来获取它(JSON)。我已为此目的提供服务:

'use strict';


angular.module('frontendApp').factory('backendService', function($resource, $location){
    var objBackend = {};

    objBackend.query = function(id) {
        var data = $resource('http://localhost:9010/API/:dataID', {dataID: id}, {
            query: {
                method: 'GET',
                headers: {'token': '1588526404200542348177491835893601182229853'}
            }
        });

        var dataForFrontEnd = data.query().$promise.then(function(d){
            console.log(d);
            return d;
        },
        function(error){
            ...
        });

        return dataForFrontEnd;
    }

    return objBackend;
});

我有一个$ resource查询方法的自定义版本,用于管理REST调用的成功和失败(以及用于发送自定义&#39;标记&#39;标头)。 我的AngularJS应用程序需要API的数据,然后我将其设置在主控制器的范围内。 我这样做是因为,如果我注入服务并调用query()方法,Angular将为每个指令调用API n次,返回完全相同的对象。而不是那样,我只在应用程序加载中调用它一次,并在所有控制器之间共享JSON数据(每个选项卡一个控制器)。

主表单控制器:

'use strict';

angular.module('frontendApp')
  .controller('MainCtrl', function ($scope, $routeParams, data, datepickerPopupConfig) {
    $scope.data = data;

    datepickerPopupConfig.showButtonBar = false;

    $scope.submit = function(){
      console.log($scope.data.val1);
    };
});

app.js:

'use strict';

angular
  .module('frontendApp', [
    'ngAnimate',
    'ngAria',
    'ngCookies',
    'ngMessages',
    'ngResource',
    'ngRoute',
    'ngSanitize',
    'ngTouch',
    'ui.bootstrap'
  ])
  .config(function ($routeProvider) {
    $routeProvider
      .when('/API/:dataID', {
        templateUrl: 'main/directives/main.html',
        controller: 'MainCtrl',
        resolve: {
          data: function(backendService, $route){
            var id = $route.current.params.dataID;
            return backendService.query(id);
          }
        }
      })
      .otherwise({
        redirectTo: '/notfound'
      });
  });

指令1(根据父作用域显示我如何绑定数据):

JS(指令):

&#39;使用严格的&#39;;

angular.module('frontendApp')
.directive('ds1', function($http){
    return {
        restrict: 'E',
        replace: true,
        scope: true,
        templateUrl: 'basic/directives/basic.html',
        controller: 'ds1'
    };
});

JS(控制器):

'use strict';


angular.module('frontendApp')
  .controller('ds1', function ($scope) {
    var data = $scope.data;

    $scope.val1 = data.val1;
    $scope.val2 = data.val2;
    $scope.val3 = data.val3;

    //Datepicker
    $scope.dpOpened = {
      val1: false,
      val2: false,
      val3: false
    };

    $scope.open = function($event, opened) {
      $event.preventDefault();
      $event.stopPropagation();
      $scope.dpOpened[opened] = true;
    };

    $scope.dateOptions = {
      formatYear: 'yy',
      startingDay: 1
    };

    $scope.format = 'yyyy-MM-dd';
    //Datepicker
});

HTML:

<div class="container-fluid">
    <h4>Data section 1</h4>
    <div class="form-group">
        <div class="col-xs-6 col-sm-3">
            <label for="value1">Value 1/label>
            <select id="value1" class="form-control" ng-model="val1" ng-required="true">
                <option value="1">X</option>
                <option value="2">Y</option>
                <option value="3">Z</option>
            </select>
        </div>

        <div class="col-xs-6 col-sm-3">
            <label for="value2">Val 2</label>
            <select id="value2" class="form-control" ng-model="val2" ng-required="true">
                <option value="A">A</option>
                <option value="B">B</option>
            </select>
        </div>

        <div class="col-xs-6 col-sm-3">
            <label for="value3">Value 3</label>
            <input id="value3" type="text" ng-model="val3" ng-required="true" disabled class="form-control"/>
        </div>
    </div>
</div>

问题(和问题):当我点击提交按钮发送表单数据时,AngularJS不识别任何更改的值。我认为我的问题是范围。当我将主对象的值复制到指令范围的值时,我看不到用户在表单中所做的更改。

问题:基于我的布局和我的描述,在所有指令之间共享数据的正确方法是什么并获得更改,知道我使用的是ng-model?< / EM>

请记住,我没有注入我的服务,因为我不想每次为每个指令调用我的API,而是希望在父控制器中返回一个API-Call和数据,但在子控制器中共享它。

提前致谢

1 个答案:

答案 0 :(得分:0)

您应该在服务中拥有该状态,并且您应该使用$ watch关注指令中的状态。

以下是关于它的简短文章:https://coderwall.com/p/dhgljg/angularjs-watch-for-changes-in-a-service

更新:如果您想要一个性能更高的解决方案,您可以为您的服务提供一个回调,它会调用数据更改。 $ watch的性能不是很好,所以你应该谨慎使用它。请参阅:AngularJS : How to watch service variables?