3

Я пробовал ответ, упомянутый here, но не повезло (я использую angularjs 1.3). Моя проблема состоит из двух частейатрибуты угловой директивы не оценены

1) Сложные атрибуты не передаются в качестве объектов, несмотря на использование «=» (см код ниже) в рамках

2) функцию, которая должна оценить, чтобы обеспечить одностороннюю связывание также передается в виде строки вместо

использования образца,

<button type="button" class="btn btn-success" ng-click="RestEditCtrl.saveRestaurantDetails();"> 
    <smart-btn-label btn-state="RestEditCtrl.ajaxState(RestEditCtrl.restaurant.id)" 
     when-normal="{label: 'Save', icon: 'glyphicon-floppy-disk' }" 
     when-active="{label: 'Saving...', icon: 'glyphicon-refresh glyphicon-spin-animate'}" 
     when-success="{label: 'Saved!', icon: 'glyphicon glyphicon-floppy-saved'}" 
     when-error="{label: 'Try saving again', icon: 'glyphicon glyphicon-exclamation-sign'}"></smart-btn-label> 
</button> 

код директивы,

angular.module("app") 
    .directive('smartBtnLabel', function() { 
     return { 
      restrict: 'E',   
      scope: { 
       btnState: '&', // not working, @ evaluates but that defeats my purpose 
       whenActive: '=', // not evaluating any which way, it always comes as string 
       whenError: '=', 
       whenSuccess: '=', 
       whenNormal: '=' 
      }, 
      link: function (scope, elem, attrs) { 
       console.log(attrs); 
       var curState = "normal", 
        curLabel = attrs.whenNormal ? attrs.whenNormal.label : "", 
        curIcon = attrs.whenNormal ? attrs.whenNormal.icon : ""; 

       if (attrs.btnState) curState = attrs.btnState; 

       if(curState == "active"){ 
        curLabel = attrs.whenActive ? attrs.whenActive.label : ""; 
        curIcon = attrs.whenActive ? attrs.whenActive.icon : "" 
       } else if(curState == "success"){ 
        curLabel = attrs.whenSuccess ? attrs.whenSuccess.label : ""; 
        curIcon = attrs.whenSuccess ? attrs.whenSuccess.icon : "" 
       } else if(curState == "error"){ 
        curLabel = attrs.whenError ? attrs.whenError.label : ""; 
        curIcon = attrs.whenError ? attrs.whenError.icon : "" 
       } 

       scope.curLabel = curLabel; 
       scope.curIcon = curIcon; 
      }, 
      template: '<span aria-hidden="true" ng-show="curIcon" class="glyphicon {{curIcon}}" ></span>' + 
         '<span ng-show="curLabel">&nbsp;{{curLabel}}</span>' 
     }; 
    }); 

Что я здесь делаю неправильно? :-(


Решение

Благодаря PSL, вот что я закончил с:

angular.module("app") 
    .directive('smartBtnLabel', function() { 
     return { 
      restrict: 'E',   
      scope: { 
       btnState: '&', 
       whenActive: '&', 
       whenError: '&', 
       whenSuccess: '&', 
       whenNormal: '&' 
      }, 
      controller: ['$scope', function($scope){ 
       var vm = this; 
       vm.props = {icon: "", label: ""}; 

       var _setProperties = function() { 
        var _btnState = "normal"; 

        if ($scope.btnState) _btnState = $scope.btnState(); 

        if (_btnState == "active" && $scope.whenActive) vm.props = $scope.whenActive(); 
        else if (_btnState == "success" && $scope.whenSuccess) vm.props = $scope.whenSuccess(); 
        else if (_btnState == "error" && $scope.whenError) vm.props = $scope.whenError(); 
        else if ($scope.whenNormal) vm.props = $scope.whenNormal(); 
       }; 

       if($scope.btnState){ 
        $scope.$watch($scope.btnState, function() { 
         _setProperties(); 
        }); 
       } 

       _setProperties(); 
      }], 
      controllerAs : "smartBtnLabelCtrl",    
      template: '<span aria-hidden="true" ng-show="smartBtnLabelCtrl.props.icon" class="glyphicon {{smartBtnLabelCtrl.props.icon}}" ></span>' + 
         '<span ng-show="smartBtnLabelCtrl.props.label">&nbsp;{{smartBtnLabelCtrl.props.label}}</span>' 
     }; 
    }); 
+1

Я думаю, что PSL проделали большую работу, отвечая на ваш вопрос, я готовил эту plunker, и я чувствовал, что мог бы добавить 2 цента, http://plnkr.co/edit/HDiiSikmGN1CYLzStoJq?p=preview Также это ценное чтение по теме http://blog-it.hypoport.de/2013/11/06/passing-functions-to-angularjs-directives/ – teleaziz

ответ

5

1) Сложные атрибуты не передаются в качестве объектов, несмотря на используя '=' (см. код ниже) в области

Это потому, что вы получаете их как attrs.whenNormal, который является строкой (JSON). Вместо этого вам просто нужно получить доступ к нему из области видимости, т. Е. scope.whenNormal. Это было бы точно так же, как scope.$eval(attrs.whenNormal) или JSON.parse(attrs.whenNormal)//provided your JSON is valid. Но двухсторонняя привязка здесь не имеет особого смысла.

2) функция, которая должна оценивать для обеспечения односторонней привязки, также передается как строка.

Это происходит потому, что при использовании функции связывания они получают оценены как добытчик со связанными значениями (вы определили связанное значение, как RestEditCtrl.restaurant.id). Inorder для доступа к значению, если функция ajaxState что-то возвращает, вам нужно сделать curState = scope.btnState(); вместо curState = attrs.btnState, в основном оценить getter, чтобы получить значение.

Plnkr

+0

Не забудьте объявить область действия: {whenNormal: знак равно –