Angular directive attributes not evaluating

I've tried the answer mentioned here but no luck (I'm using angularjs 1.3). My problem has two parts

1) Complex attributes are not passed as objects, despite using '=' (see code below) in scope

2) the function that must evaluate to provide one-way binding is also passed as a string instead

sample selection,

<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>

      

directive code,

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>'
        };
    });

      

What am I doing wrong here?: --(


Decision

Thanks to PSL, this is what I got:

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>'
        };
    });

      

+3


source to share


1 answer


1) Complex attributes are not passed as objects, despite using '=' (see code below) in scope

This is because you get them as attrs.whenNormal

, which is a string (JSON). Instead, you just need to access it from the scope, i.e. scope.whenNormal

... It will be the same as scope.$eval(attrs.whenNormal)

or JSON.parse(attrs.whenNormal)//provided your JSON is valid

. But two-way binding doesn't make much sense here.

2) the function that needs to evaluate to provide one-way binding is also passed as a string.



This is because when you use function bindings, they are evaluated as a getter with the bound values ​​(you specified the bound value as RestEditCtrl.restaurant.id

). Inorder to access the value, if the function ajaxState

returns something you need to do curState = scope.btnState();

instead curState = attrs.btnState

, basically evaluate the getter to get the value.

Plnkr

+5


source







All Articles