1

呃,我被困在其中一个 Angular 绑定(不是双关语)中,我无法让我的控制器与我的指令对话。

我的指令如下,一个带有模板的选择下拉菜单:

app.directive('month', function() {
  return {
    replace:true,
    scope:{
     months:"=",
     monthChoice:"="
   },
    template:'<select ng-model="monthChoice" ng-options=\"currMonth for currMonth in months\" class=\"monthsClass\"></select>',
    link: function (scope, element, attrs) {

      var lastEntry = scope.months.length - 1;
      scope.monthChoice = scope.months[lastEntry];

      scope.$watch('monthChoice', function() {
        console.log(scope.monthChoice);
      });
    }
  }
})

填充选择的months值来自与控制器通信的服务:

app.controller('CandListCtrl', ['$scope', 'Months',
  function ($scope, Months) {

    $scope.months = Months.init();

    $scope.$watch('monthChoice', function() {
        console.log($scope.monthChoice);
      });

    $scope.whichMonth = function(m) {
      console.log(m);
      console.log($scope.month);
      return true
    }

  }]);

我想做的是在monthChoice发生变化时将模型的值传递给控制器​​。这样,我可以从部分视图中的其他 html 元素访问它。我的局部视图设置如下:

<month months="months" ng-change="whichMonth(monthChoice)"></month><br>

它位于使用典型 $routeProvider 路由的部分内部:

app.config(['$routeProvider',
  function($routeProvider) {
    $routeProvider.
      when('/', {
        templateUrl: 'partials/cand-list.html',
        controller: 'CandListCtrl'
      }).
      otherwise({
        redirectTo: '/'
      });
  }]);

我抛出以下错误:Expression 'undefined' used with directive 'month' is non-assignable!

而且我无法从控制器访问值。

4

2 回答 2

2

这更像是一个评论,但在那里发布代码很尴尬。我想知道你为什么在这里指定monthChoice

scope:{
     months:"=",
     monthChoice:"="
   }

然后尝试在您的链接功能中重新分配它?

编辑:我想我会使用你已经拥有的 Months 服务并在那里设置 monthChoicce 变量。然后它很容易在其他控制器中重用,你有什么:

app.directive('month', function(Months) {
  return {
    replace:true,
    scope:{
     months:"="

   },
    template:'<select ng-model="service.monthChoice" ng-options=\"currMonth for currMonth in months\" class=\"monthsClass\"></select>',
    link: function (scope, element, attrs) {

      var lastEntry = scope.months.length - 1;
      scope.service = Months;

      scope.$watch('monthChoice', function() {
        console.log(scope.monthChoice);
      });
    }
  }
})

编辑:做了更新。您必须绑定到一个对象,在这种情况下,我使用服务对象本身,以便在整个过程中反映更改。这是因为当您将 javascript 对象设置为另一个对象时,它们会通过引用链接。

更多编辑

好的,这是另一个与您最初尝试做的更多匹配的尝试。没有服务或其他魔法。这是控制器:

.controller('myController', function($scope) {
    $scope.months = [
        'Jan',
        'Feb',
        'Mar'
    ];
    $scope.monthChosen = '';
})

只是一个简单的月份数组和我们的 monthChosen 变量,我们将所有这些都发送到指令。monthChosen 会通过 ng-model 和双向绑定自动改变。这是我们的路线模板:

<div data-ng-app="myApp" data-ng-controller="myController">
    <div data-my-directive months="months" month-choice="monthChosen"></div>
    <div>{{monthChosen}}</div>    
</div>

您可以看到在指令之外显示monthChosen。当您更改下拉菜单时,它会更改。这是我们的指令:

.directive('myDirective', function(){
    function link(scope, elem, attrs){
        //You can do fun stuff here if you want        
    }
    return {
        scope: {
            months: '=',
            monthChoice: '='
        },
        link: link,
        template: '<select ng-model="monthChoice" ng-options="currMonth for currMonth in months" class="monthsClass"></select>'
    }
});

在这一点上,除了我们的模板和范围定义之外,它不包含任何其他内容。如您所见,您不必自己设置monthChoice,因为角度会处理这个问题:)

jsfiddle:http: //jsfiddle.net/vt52bauu/

monthChosen(控制器)<=> monthChoice(指令)

于 2015-02-22T23:06:50.847 回答
1

您可以简单地使用您的指令并ngModel通过ngModel.NgModelController. 例如...

app.directive('month', function() {
  return {
    restrict: 'E',
    replace: true,
    require: 'ngModel',
    scope: {
      months: '='
    },
    template: '<select class="monthsClass" ng-options="month for month in months"></select>',
    link: function(scope, element, attr, modelController) {
      modelController.$setViewValue(scope.months[scope.months.length - 1]);
      modelController.$render();
    }
  }
});

<month ng-model="month" months="months"></month>

Plunker

于 2015-02-22T23:37:33.730 回答