2013-02-28 3 views
3

Моя проблема заключается в создании угловой директивы.Угловое двустороннее связывание с вспомогательными элементами

Я хочу создать группу флажков с помощью только одной ng-модели. Это похоже на битовое поле или флаги, т. Е. Флажки имеют значения от 0, 1, 2, 3 до n, но для ng-модели я просто хочу добавить значение 2^всех отмеченных флажков. Значения для добавления - это 1, 2, 4, 8, 16, ...

Интересно, есть ли лучшее, более правильное или просто более простое решение моей проблемы.

http://plnkr.co/edit/9h7EkEpDohXTniIDHdc5

В примере вы можете изменить значение в текстовом поле и проверки будут обновлены, но не наоборот. Это немного сумасшедший, код работает на моей машине dev, но не в Plnkr!

app.directive('ngCheckboxFlags', function() { 
return { 
    restrict: 'A', 
    require: 'ngModel', 
    link: function (scope, element, attrs, ctrls) { 
     var flagSum; 
     var checkboxes = []; 

     // trigger changes of the ngModel 
     scope.$watch(attrs.ngModel, function (value) { 
      flagSum = value; 
      for (var i = 0, ii = checkboxes.length; i < ii; ++i) { 
       var checkbox = checkboxes[i]; 
       checkbox.checked = flagSum & (1<<checkbox.value); 
      } 
     }); 

     for (var i = 0, inputs = element.find('input[type=checkbox]'), ii = inputs.length; i < ii; ++i) 
     { 
      var checkbox = inputs[i]; 
      checkboxes.push(checkbox); 
      // trigger changes of HTML elements 
      $(checkbox).bind('change', function() { 
       flagSum = ctrls.$viewValue^(1<<this.value); 
       console.log(flagSum); 

       //ERROR: Change not happening, textbox shows old value 
       scope.$apply(function() { 
        ctrls.$setViewValue(flagSum); 
       }); 
      }); 
     } 
    } 
}; 
}); 

Thnx заранее Кнут

+0

Ну, ваш plunker не работает, потому что вы вяжете непосредственно на уровень области. Всегда привязывайте свойство объекта (объекта к области). Смотрите это, чтобы понять, что я имею в виду: http://plnkr.co/edit/jgoMWDssothUlSy1oelP?p=preview. Что касается вашего фактического вопроса, «есть ли лучший способ?», Я не настолько эксперт, поэтому я бы сказал, что просто придерживайтесь того, что сейчас работает. – finishingmove

+0

Забавный! Именно поэтому это было правильно в моей машине dev (там у меня сложный объект) и не работает на plnkr. Просто хотел упростить код для моего вопроса и поэтому использовал примитивный тип. Лучше не делать в будущем :( – kwrl

ответ

5

Не связывайте ng-model непосредственно к примитивным типам, используйте объект вместо:

$scope.sum = { 
    ofCheckValues: 3 
}; 

А на HTML:

ng-model="sum.ofCheckValues" 

«Всякий раз, когда у вас есть ng-модель, есть где-то там. Если вы не имеете точку, вы делаете это неправильно «

plunker:. http://plnkr.co/edit/NRAk3kyP1rdDmYrsz6ZL?p=preview

+0

Благодарим вас за tipp. Как уже упоминалось выше (в комментарии), именно поэтому в моей машине dev было нормально, но я все еще не уверен, что мое решение - хороший способ для угловой или если есть более «угловой путь». – kwrl

+0

IMHO кажется хорошим решением ... – bmleite

1

Найдено более элегантный и более короткий путь: http://plnkr.co/edit/9h7EkEpDohXTniIDHdc5

Моя проблема была

  • не понял, что для каждого элемента вызывается ссылка()
  • поэтому каждый раз, когда новый «объем» является c (для каждого элемента)
  • Мне просто нужно сохранить ссылку на фактический элемент в моей переменной (теперь называемый флажком; был массив в первой версии) для его обновления, когда модель изменяется (область. $ watch)
  • Мне не нужен «глобальный» флагSum, только локальный в привязке к флажку для передачи значения в сфера. $ применять

    app.directive('ngCheckboxFlags', function() { 
        return { 
        restrict: 'A', 
        require: 'ngModel', 
        link: function (scope, element, attrs, ctrls) { 
         var checkbox = element.find('input[type=checkbox]')[0]; 
         if (typeof checkbox === "undefined") 
          return; 
    
         // trigger changes of the ngModel 
         scope.$watch(attrs.ngModel, function (value) { 
          checkbox.checked = value & (1<<checkbox.value); 
         }); 
    
         $(checkbox).bind('change', function() { 
          var flagSum = ctrls.$viewValue^(1<<this.value); 
    
          scope.$apply(function() { 
           ctrls.$setViewValue(flagSum); 
          }); 
         }); 
        } 
        }; 
    }); 
    
+1

Просто хочу сказать, что это действительно помогло мне с очень похожей проблемой, поэтому спасибо за публикацию. – Dave

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