Directive does not run link function when attribute changes value

允我心安 提交于 2020-01-05 17:46:01

问题


I have created a directive for encapsulating qTip2 library into my angular application (as described in another SO question) . I have a dictionary with different configurations for qTip and depending on the value I pass on the attribute cv-tooltip the appropriate configuration is passed in the .qtip call in the link function. This works fine for directives that are set in html (eg. shows a qtip on the right and cv-tooltip="left" on the left).

Problem arises when I change the value of the attribute from cv-tooltip="right" to cv-tooltip="left" from another directive, the tooltip directive link function does not re-run when the value changes and thus the qTip is not updated with the correct configuration.

qtip directive looks like this:

    mainApp.directive('cvTooltip', function () {
        var optionDictionary = {
            'right': {
                position: {
                    my: 'center left',
                    at: 'right center'
                },
                style: {
                    tip: {
                        corner: 'left center',
                        height: 10
                    }
                }
            },
            'left': {
                position: {
                    my: 'center right',
                    at: 'left center'
                },
                style: {
                    tip: {
                        corner: 'right center',
                        height: 10
                    }
                }
            }
        };


        return {
            restrict: 'A',
            scope: {
                positionType: '=cvTooltip'
            },
            link: function (scope, element, attrs) {

                var options = {
                    style: {
                        tip: {
                            width: 13
                        }
                    },
                    position: {
                        target: element
                    }
                };
                var defaults = optionDictionary[scope.positionType];
                $.extend(options, defaults);
                element.qtip('destroy');
                element.qtip(options);

            }
        }
    }
);

Other directive looks like:

    mainApp.directive('cvErrorOnBlur', ['$compile', function () {
    return {
        restrict: 'A',
        require: 'ngModel',
        replace: true,
        link: function (scope, element, attributes, controller) {
            element.bind("blur", function () {
                if (controller.$dirty && controller.$invalid) {
                    element.addClass('error');
                    element.attr('cv-tooltip', 'left');

                } else {
                    element.removeClass('error');
                    element.attr('cv-tooltip', 'right');

                }
            });
        }
    }
}]);

In html I use it like

 <input type="text" cv-tooltip="right" cv-error-on-blur />

回答1:


You would have to use $observe or $watch to monitor changes to the attribute, but the value of the attribute would have to be interpolated ({{}})

Example:

<input type="text" cv-tooltip="{{right}}" cv-error-on-blur />

attrs.$observe('cvTooltip', function(newValue, oldValue) {

});

Could you just rewrite it into a single directive?

mainApp.directive('cvTooltip', function () {
    var optionDictionary = {
        'right': {
            position: {
                my: 'center left',
                at: 'right center'
            },
            style: {
                tip: {
                    corner: 'left center',
                    height: 10
                }
            }
        },
        'left': {
            position: {
                my: 'center right',
                at: 'left center'
            },
            style: {
                tip: {
                    corner: 'right center',
                    height: 10
                }
            }
        }
    };


    return {
        restrict: 'A',
        require:"^ngController",
        link: function (scope, element, attrs, controller) {
            var initialValue = attrs.cvTooltip;
            console.log(initialValue);
            var options = {
                style: {
                    tip: {
                        width: 13
                    }
                },
                position: {
                    target: element
                }
            };
            if (controller.$dirty && controller.$invalid) {
                element.addClass('error');
                var defaults = optionDictionary['left'];
                $.extend(options, defaults);
                element.qtip('destroy');
                element.qtip(options);

            } else {
                element.removeClass('error');
                var defaults = optionDictionary['right'];
                $.extend(options, defaults);
                element.qtip('destroy');
                element.qtip(options);
            }
        }
    }


来源:https://stackoverflow.com/questions/20399311/directive-does-not-run-link-function-when-attribute-changes-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!