如何将现有属性及其值替换为自定义指令并在指令

时间:2017-06-19 15:12:22

标签: javascript angularjs angularjs-directive

我正在使用图像后备并为此制作工厂,

控制器

(function () {
    'use strict';

    angular
        .module('app')
        .controller('myCtrl', myCtrl);

    /* @ngInject */
    function myCtrl(GetInitials) {

        var vm = this;

        vm.getInitials = function(name){
            return GetInitials.getInitials(name);
        };

    }
})();

在HTML中我使用图像回退

<img class="md-avatar" fallback-src="{{vm.getInitials(user.name)}}" ng-src="/assets/images/other/random.jpg"/>

工厂

(function() {
    'use strict';

    angular
        .module('app')
        .factory('GetInitials', Service);

    /* @ngInject */
    function Service() {

        var getInitials = function(name) {

            var nameArray = name.split(" ");

            if(nameArray.length > 1){
                name = {
                        first : nameArray[0],
                        last : nameArray[1]
                       };
            } else {
                name = {
                    first : nameArray[0].charAt(0),
                    last : nameArray[0].charAt(1)
                };
            }

            var canvas = document.createElement('canvas');
            canvas.style.display = 'none';
            canvas.width = '45';
            canvas.height = '45';
            document.body.appendChild(canvas);
            var context = canvas.getContext('2d');
            context.fillStyle = "dodgerblue";
            context.fillRect(0, 0, canvas.width, canvas.height);
            context.font = "20px Roboto, 'Helvetica Neue, sans-serif";
            context.fillStyle = "#fff";
            var first, last;
            if (name && name.first && name.first != '') {
                first = name.first[0];
                last = name.last && name.last != '' ? name.last[0] : null;
                if (last) {
                    var initials = first + last;
                    context.fillText(initials.toUpperCase(), 10, 30);
                } else {
                    var initials = first;
                    context.fillText(initials.toUpperCase(), 20, 33);
                }
                var data = canvas.toDataURL();
                document.body.removeChild(canvas);
                return data;
            } else {
                return false;
            }
        };
        return {
            getInitials: getInitials
        };
    }
})();

相反,我想为它创建一个指令,以便不在每个控制器中调用工厂并全局使用指令。我试图做一些分数,称为函数及其总是抛出错误,我很困惑如何使用指令将image-fallback-initials my-user="User Name"替换为原始fallback-src="{{vm.getInitials(user.name)}}"

   <img class="md-avatar" image-fallback-initials my-user="User Name" ng-src="/assets/images/other/easde.jpg"/>

相同的指令

   (function () {
    'use strict';

    angular
        .module('app')
        .directive('imageFallbackInitials', imageFallbackInitials);

    /* @ngInject */
    function imageFallbackInitials() {

        return {
            restrict : "A",
            priority: 200,
            controller: function($scope) {
                // bind myVar property to scope
                $scope.getInitials = function(name) {

                    var nameArray = name.split(" ");

                    if(nameArray.length > 1){
                        name = {
                            first : nameArray[0],
                            last : nameArray[1]
                        };
                    } else {
                        name = {
                            first : nameArray[0].charAt(0),
                            last : nameArray[0].charAt(1)
                        };
                    }

                    var canvas = document.createElement('canvas');
                    canvas.style.display = 'none';
                    canvas.width = '45';
                    canvas.height = '45';
                    document.body.appendChild(canvas);
                    var context = canvas.getContext('2d');
                    context.fillStyle = "dodgerblue";
                    context.fillRect(0, 0, canvas.width, canvas.height);
                    context.font = "20px Roboto, 'Helvetica Neue, sans-serif";
                    context.fillStyle = "#fff";
                    var first, last;
                    if (name && name.first && name.first != '') {
                        first = name.first[0];
                        last = name.last && name.last != '' ? name.last[0] : null;
                        if (last) {
                            var initials = first + last;
                            context.fillText(initials.toUpperCase(), 10, 30);
                        } else {
                            var initials = first;
                            context.fillText(initials.toUpperCase(), 20, 33);
                        }
                        var data = canvas.toDataURL();
                        document.body.removeChild(canvas);
                        return data;
                    } else {
                        return false;
                    }
                };
            },
            link : function(scope,elements,attrs){

               attrs.$set('fallback-src', scope.getInitials(attrs.myUser));
            }
        }
    }
})();

已编辑:更新指令并且工作正常。

这里我得到的是fallback-src,但它没有显示姓名首字母,

进行控制台检查

我在这里得到ng-src, fallback-src and then src

使用工厂时,序列为fallback-src ng-src and then src

所以fallback-src正在更新但是它没有更新src和src仍然是旧的

2 个答案:

答案 0 :(得分:1)

您错误地匹配了link函数参数的顺序。传递给指令link函数的参数是scopeelementsattrs,因此链接函数应为

link : function(scope,elements,attrs){
    console.log(attrs.myUser);
}

如果要在范围内注册观察者,则应在指令定义中使用scope选项

return {
    restrict : "A",
    scope: {
        myUser: '@'
    },
    link : function(scope,elements,attrs){
        console.log(scope.myUser);
    }
}

答案 1 :(得分:0)

已经完成了创建

的完整解决方案

名称缩写的图像回退指令| AngularJs

完整的端到端工作代码在这里:

How to update the src with new fallback-src using the directive?

其他方法也可以提供更多答案。