4

我的服务 NavData

angular.module('navData', []).
    factory('NavData', function() {
        var navData = {};
        navData.depth = 0;
        navData.category_id = "";
        navData.category_name = "";
        navData.subcategory_id = "";
        navData.subcategory_name = "";
        return navData;
    });

在某些页面上从 ui-router 接收值:

  var category = { 
    name: 'category',
    parent: site,
    url: '/categories/:category_id',
    onEnter: function(NavData, $stateParams){
      NavData.depth = 1;
      NavData.category_id = $stateParams.category_id;
      console.log(NavData);         
    },
    views: {
      'navigation': {
      templateUrl: 'partials/category-menu.html'
      },
      'content': {
      templateUrl: 'partials/category-images.html'
      }
    }
  };

出现在所有页面上的指令应注意服务中的更改并将它们反映在自定义面包屑功能中:

  .directive('breadcrumb', ['NavData', function(NavData){
    return {
      templateUrl: 'partials/breadcrumb.html',
      link: function(scope, elm, attrs, ctrl){
        scope.depth            = NavData.depth;
        scope.category_id      = NavData.category_id;
        scope.category_name    = NavData.category_name;
        scope.subcategory_name = NavData.subcategory_name;

        var doStuff = function(navdata){
          console.log("watching depth: " + navdata.depth);
          console.log("watching cat_id: "+ navdata.category_id);
        };
        scope.$watch(NavData.depth, doStuff(NavData), true);
        scope.$watch(NavData.category_id, doStuff(NavData), true);
      }

    };
  }])

但是, scope.$watch 似乎不起作用。这是我的日志:

watching depth: 0 directives.js:28
watching cat_id:  directives.js:29
watching depth: 0 directives.js:28
watching cat_id:  directives.js:29
Object {depth: 1, category_id: "1", category_name: "", subcategory_id: "", subcategory_name: ""} app.js:25

我究竟做错了什么?

4

2 回答 2

7

您的第一个错误出现在第scope.$watch()一个参数中:它是在给定中评估的表达式(字符串)scope,或者是返回值的函数;该值被存储并且该函数在每个摘要循环中运行;如果新值不同,则触发侦听器(第二个参数)。

所以第一个修正是:

scope.$watch(function() {
    return NavData.depth,
}, .../*other arguments, see below*/);

现在第二个论点也是错误的!它应该是一个函数,您提供的是一个函数的返回值(顺便说一下,它是未定义的doStuff)。这个第二个参数函数接收新值(由上面的第一个参数返回)、旧值和范围。在您的情况下,您不关心新/旧值。所以完整的解决方案应该是:

scope.$watch(function() { // decide the watched value
    return NavData.depth,
}, function() { // what to do when the value changes
    // do stuff and reference NavData normally
});
于 2013-09-22T19:33:40.710 回答
0

假设NavData仅通过ui-router onEnter回调进行更改,您可能会跳过整个NavData对象和$watch实现。

onEnter只需在每个回调上广播一个事件:

onEnter: function($rootScope, $stateParams){
   $rootScope.$broadcast("NavDataChanged", {
       depth: 1,
       category_id: $stateParams.category_id
       /* (any other former NavData properties) */
   });
}

您的指令将变为:

.directive('breadcrumb', [function(){
    return {
      templateUrl: 'partials/breadcrumb.html',
      link: function(scope, elm, attrs, ctrl){
        scope.$on("NavDataChanged", function(event, navData) {
            scope.depth = navData.depth;
            scope.category_id = navData.category_id;
            // any other former NavData properties and doStuff code
        });
      }
    };
  }])

简化版在这里

于 2013-10-31T16:46:25.010 回答