0

Попытка написать пользовательскую директиву, что кнопка отображения в качестве дня в неделюпользовательская директива кнопка подсветки

как показано на рисунке ниже.

enter image description here

Это то, что я до сих пор и имеют проблемы связывания с нг-модель обратно директиву.

Первоначально кнопка белая и в зависимости от модели в настоящее время передаются в виде массива

$scope.selectedDays = ["mon", "wed"]; 

Для приведенного выше примера понедельник и среда должны быть выделены серым цветом. все остальные должны быть белыми.

Любая идея?

app.directive('daysDirective', function ($compile) { 

    var days = [ 
     { key: "sun", display: "S"}, 
     { key: "mon", display: "M"}, 
     { key: "tue", display: "T"}, 
     { key: "wed", display: "W"}, 
     { key: "thurs", display: "T"}, 
     { key: "fri", display: "F"}, 
     { key: "sat", display: "S"} 
    ]; 

    //var template = 
    //  ' <div class="input-group">'+ 
    //  '  <button ng-repeat="day in days track by $index" ng-class="{\'btn btn-sm btn-white\': day.selected, \'btn btn-sm btn-grey\': !day.selected}">{{ day.display }}</button>' + 
    //  ' </div>'; 

    var template = 
     ' <div class="input-group">'+ 
     '  <button ng-class="{\'btn btn-sm btn-white\': day.selected, \'btn btn-sm btn-grey\': !day.selected}">S</button>' + 
     '  <button ng-class="{\'btn btn-sm btn-white\': day.selected, \'btn btn-sm btn-grey\': !day.selected}">M</button>' + 
     '  <button ng-class="{\'btn btn-sm btn-white\': day.selected, \'btn btn-sm btn-grey\': !day.selected}">T</button>' + 
     '  <button ng-class="{\'btn btn-sm btn-white\': day.selected, \'btn btn-sm btn-grey\': !day.selected}">W</button>' + 
     '  <button ng-class="{\'btn btn-sm btn-white\': day.selected, \'btn btn-sm btn-grey\': !day.selected}">T</button>' + 
     '  <button ng-class="{\'btn btn-sm btn-white\': day.selected, \'btn btn-sm btn-grey\': !day.selected}">F</button>' + 
     '  <button ng-class="{\'btn btn-sm btn-white\': day.selected, \'btn btn-sm btn-grey\': !day.selected}">S</button>' + 
     ' </div>'; 

    var linker = function (scope, element, attrs, ngModelCtrl) { 

     element.html(template).show(); 
     $compile(element.contents())(scope); 
    }; 

    return { 
     require: 'ngModel', 
     link: linker, 
     replace: true, 
     restrict: 'EA', 
     scope: { 
      model: '=ngModel' 
     }, 
     controller: ['$scope', function ($scope) { 
      $scope.days = days; 
      var model = $scope.model; 

      //$scope.selected = model[] 
     }] 
    }; 

}); 

ответ

0

Вы можете упростить вашу директиву, используя свойство шаблона

app.directive('daysDirective', function() { 
    return { 
     require: 'ngModel', 
     link: function(scope, element, attr, ngModelController) { 
      //not required, unless you are actually going to use ngModelController 
     }, 
     replace: true, 
     restrict: 'EA', 
     template: ' <div class="input-group">' + 
        '  <button ng-repeat="(key, day) in days track by $index" ng-class="{\'btn btn-sm btn-white\': day.selected, \'btn btn-sm btn-grey\': !day.selected}">{{ day.display }}</button>' + 
        ' </div>', 
     scope: { 
      model: '=ngModel' 
     }, 
     controller: ['$scope', function ($scope) { 
      //this needs to move into your controller, because otherwise all instances will share the same instance of days, causing them to interfere with each other 
      $scope.days = { 
       sun: { display: "S"}, 
       mon: { display: "M"}, 
       tue: { display: "T"}, 
       wed: {display: "W"}, 
       thurs: { display: "T"}, 
       fri: { display: "F"}, 
       sat: { display: "S"} 
      }; 


      $scope.$watchCollection('model', function(){ 
       //clear the selected attribute 
       for(var i in $scope.days) { 
        $scope.days[i].selected = false; 
       } 

       for(var i in $scope.model) { 
        $scope.days[$scope.model[i]].selected = true; 
       } 


      }); 
     }] 
    }; 

}); 

Вы можете избежать сложности часов в целом:

app.directive('daysDirective', function() { 

      var days = { 
       sun: { display: "S"}, 
       mon: { display: "M"}, 
       tue: { display: "T"}, 
       wed: {display: "W"}, 
       thurs: { display: "T"}, 
       fri: { display: "F"}, 
       sat: { display: "S"} 
      }; 
    return { 
     require: 'ngModel', 
     link: function(scope, element, attr, ngModelController) { 
      //not required, unless you are actually going to use ngModelController 
     }, 
     replace: true, 
     restrict: 'EA', 
     template: ' <div class="input-group">' + 
        '  <button ng-click="Toggle(day)" ng-repeat="day in days track by $index" ng-class="{\'btn btn-sm btn-white\': isSelected(day.key), \'btn btn-sm btn-grey\': !isSelected(day.key)}">{{ day.display }}</button>' + 
        ' </div>', 
     scope: { 
      model: '=ngModel' 
     }, 
     controller: ['$scope', function ($scope) { 

      $scope.days = days; 
      $scope.isSelected = function(day) { 
       return $scope.model.indexOf(day) > -1 

      } 

      $scope.Toggle = function(day) { 
       var idx = $scope.model.indexOf(day.key); 
       if(idx > -1) 
        $scope.model.splice(idx, 1); 
       } 
       else { 
        $scope.model.push(day.key); 
       } 

      } 


     }] 
    }; 

}); 
+0

Благодаря Джо! модель также должна быть обновлена ​​с помощью массива выбранных пользователем дней. Как вы можете это сделать, не используя часы на модели? – ove

+0

Вы уже это сделали. Просто обновите массив, который вы передаете в параметр «model». Это сработает. –

+0

Возможно, я не правильно перефразировал, я хочу $ scope.selectedDays быть обновленным с выбранным пользователем пользователем днем. если пользователь выбирает mon, tue, wed then scope.selectedDays = ["mon", "tue", "wed"]; Я храню scope.selectedDays. – ove

Смежные вопросы