AngularJS,更新控制器和html之间的范围

时间:2017-05-31 21:11:40

标签: angularjs

我已经构建了一个跟踪telerik网格中记录的id的服务。在网格中选择行时,服务会成功触发并更新数据。我的问题是处理我的导航的控制器没有看到变化,我不完全理解如何实现这一点,因为我对angularjs和前端开发相当新。



app
  .controller('FindCardCtrl', ['$scope', '$http', 'NavService', function($scope, $http, NavService) {


    $http.get('../../sampleData/cardData.json').then(function(data) {

      var cardObj = data.data.cards;


      var grid = $("#grid").kendoGrid({
        dataSource: {
          data: cardObj.card,
        },
        columns: [{
            hidden: true,
            field: "id"
          },
          {
            field: "card_number",
            title: "Card Number"
          },
          {
            field: "name_on_card",
            title: "Name On Card"
          },
          {
            field: "billing_zip_code",
            title: "Billing Zip Code"
          },
          {
            field: "balance",
            title: "Balance"
          }
        ],
        noRecords: true,
        editable: false,
        sortable: true,
        reorderable: true,
        selectable: "row",
        change: function(e) {
          var selectedRows = this.select();

          var selectedDataItems = [];
          for (var i = 0; i < selectedRows.length; i++) {
            var dataItem = this.dataItem(selectedRows[i]);
            selectedDataItems.push(dataItem);
          }

          NavService.setCardId(selectedDataItems[0].id);

        },
        pageable: {
          pageSize: 20,
          previousNext: true,
          input: true,
          buttonCount: 5,
          pageSizes: [20, 30, 40, "all"],
          info: true,
          messages: {
            page: "Enter page"
          }
        },
        filterable: {
          mode: "menu",
          ignoreCase: true,
          operators: {
            string: {
              eq: "Equal to",
              contains: "Contains",
              startswith: "Begins with"
            },
            date: {
              eq: "Equal to",
              gt: "After",
              lt: "Before",
              eq: "Equals",
              gte: "After or equal to",
              lte: "Before or equal to"
            }
          }
        }
      });
    });
  }]);
&#13;
&#13;
&#13;

&#13;
&#13;
'use strict';


app
  .controller('NavCtrl', ['$scope', '$http', 'NavService', function($scope, $http, NavService) {
    $scope.oneAtATime = false;

    //$http.get('../../sampleData/cardData.json').then(function (data) {
    //var card = getObjects(data, "id", NavService.cardData.cardId);

    //  });
    $scope.$on('card-selected', function(event, NavService) {
      console.log(NavService.cardData.cardId);
    });
    //  console.log(NavService.cardData.cardId);
    //$scope.cardId = NavService.cardData.cardId;

    $scope.status = {
      isFirstOpen: true
    };
  }]);



function getObjects(obj, key, val) {
  var objects = [];
  for (var i in obj) {
    if (!obj.hasOwnProperty(i)) continue;
    if (typeof obj[i] == 'object') {
      objects = objects.concat(getObjects(obj[i], key, val));
    } else if (i == key && obj[key] == val) {
      objects.push(obj);
    }
  }
  return objects;
}
&#13;
&#13;
&#13;

&#13;
&#13;
'use strict';

/**
 * @ngdoc overview
 * @name backOfficeApp
 * @description
 * # backOfficeApp
 *
 * Main module of the application.
 */

/*jshint -W079 */

var app = angular
  .module('backOfficeApp', [
    'ngAnimate',
    'ngCookies',
    'ngResource',
    'ngSanitize',
    'ngTouch',
    'ngMessages',
    'picardy.fontawesome',
    'ui.bootstrap',
    'ui.router',
    'ui.utils',
    'angular-loading-bar',
    'angular-momentjs',
    'kendo.directives',
    'FBAngular',
    'lazyModel',
    'angularBootstrapNavTree',
    'angularFileUpload',
    'oc.lazyLoad',
    'ui.select',
    'ui.tree',
    'ui.calendar',
    'pascalprecht.translate',
    'ngMaterial',
    'localytics.directives',
    'ipsum',
    'angular-intro',
    'dragularModule'
  ])
  .run(['$rootScope', '$state', '$stateParams', function($rootScope, $state, $stateParams) {
    $rootScope.$state = $state;
    $rootScope.$stateParams = $stateParams;
    $rootScope.$on('$stateChangeSuccess', function(event, toState) {

      event.targetScope.$watch('$viewContentLoaded', function() {

        angular.element('html, body, #content').animate({
          scrollTop: 0
        }, 200);

        setTimeout(function() {
          angular.element('#wrap').css('visibility', 'visible');

          if (!angular.element('.dropdown').hasClass('open')) {
            angular.element('.dropdown').find('>ul').slideUp();
          }
        }, 200);
      });
      $rootScope.containerClass = toState.containerClass;
    });
  }])

  .config(['uiSelectConfig', function(uiSelectConfig) {
    uiSelectConfig.theme = 'bootstrap';
  }])

  //angular-language
  .config(['$translateProvider', function($translateProvider) {
    $translateProvider.useStaticFilesLoader({
      prefix: 'languages/',
      suffix: '.json'
    });
    $translateProvider.useLocalStorage();
    $translateProvider.preferredLanguage('en');
    $translateProvider.useSanitizeValueStrategy(null);
  }])
  .config(['$provide', function($provide) {
    $provide.factory('NavService', function($q) {
      var dataHolder = {};
      //It's important that you use an object or an array here a string or other
      //primitive type can't be updated with angular.copy and changes to those
      //primitives can't be watched.
      dataHolder.cardData = {
        "cardId": '0'
      };

      dataHolder.setCardId = function(id) {
        var deferred = $q.defer();
        var cardId = id;
        angular.copy(cardId, dataHolder.cardData);

        deferred.resolve(dataHolder.cardData);
        return deferred.promise;
      }
      return dataHolder;
    })

  }])
&#13;
&#13;
&#13;

&#13;
&#13;
<div id="sidebar-wrap" ng-controller="NavCtrl">
  <uib-accordion close-others="oneAtTime" slimscroll="{height: '100%'}">
    <div uib-accordion-group is-open="status.isFirstOpen" class="panel-default">

      <ul id="navigation" nav-collapse ripple>
        <li ui-sref-active="active">
          <a ui-sref="client.dashboard">
            <fa name="dashboard"></fa> <span>{{ 'Menu.DASHBOARD'| translate }}</span></a>
        </li>
        <li ui-sref-active="active" ng-class="{'open':$state.includes('client.order')}">
          <a ui-sref="client.order">
            <fa name="shopping-cart"></fa> <span>{{ 'Menu.ORDER_MANAGEMENT' | translate }}</span></a>
          <ul>
            <li ui-sref-active="active">
              <a ui-sref="client.order_management.new">
                <fa name="caret-right"></fa> {{ 'Menu.NEW_ORDER' | translate }}</a>
            </li>
            <li ui-sref-active="active">
              <a ui-sref="client.order_management.history">
                <fa name="caret-right"></fa> {{ 'Menu.HISTORY' | translate }}</a>
            </li>
            <li ui-sref-active="active">
              <a ui-sref="client.order_management.cancel">
                <fa name="caret-right"></fa> {{ 'Menu.CANCEL' | translate }}</a>
            </li>
          </ul>
        </li>
        <li ui-sref-active="active" ng-class="{'open':$state.includes('client.card')}">
          <a ui-sref="client.card">
            <fa name="credit-card"></fa> <span>{{ 'Menu.CARD_MANAGEMENT' | translate }}</span></a>
          <ul>
            <li ui-sref-active="active">
              <a ui-sref="client.card_management.find">
                <fa name="search"></fa> {{ 'Menu.FIND_CARD' | translate }}</a>
            </li>
          </ul>
          <ul ng-if="cardId > 0">
            <li ui-sref-active="active">
              <a ui-sref="client.card_management.summary({cardId: cardId})">
                <fa name="caret-right"></fa> {{ 'Menu.SUMMARY'| translate }} </a>
            </li>
          </ul>
        </li>
      </ul>
    </div>
  </uib-accordion>
</div>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:0)

您可以使用Angular中的事件系统通知其他控制器他们需要更新其值:

app.service('MyService', function($rootScope) {
  var MyService = this;
  var item;
  MyService.setItem = function(value) {
    /*-- code to set item --*/

    // notify other controllers
    $rootScope.$broadcast('item-changed');

  };

  MyService.getItem = function() {
    // api call to get item
    // or get current item value from variable
  };

});


app.controller('MyOtherController', function($scope, MyService) {

  $scope.$on('item-changed', function() {
    MyService.getItem().then(function(result) {
      $scope.item = result;
    });
  });

});

在你的NavCtrl中,你大部分都在那里,你只需要在你的事件监听器中将范围变量设置为新的cardId

  .controller('NavCtrl', [
     '$scope', '$http', 'NavService', 
     function($scope, $http, NavService) {
       //...
       $scope.$on('card-selected', function(event, NavService) {
         console.log(NavService.cardData.cardId);
         $scope.cardId = NavService.cardData.cardId;
       });
       //...
  }]);

您无法将$scope注入服务,但可以注入$rootScope。在$rootScope上广播事件并将其发送到所有范围。任何正在倾听它的范围都能够响应它。