Angular directive fields not require brackets

2019-09-02 05:43发布

问题:

I'm using UI Bootstrap's datepicker function and I'd like to get ahold of one of the values passed into an attribute.

// JS
$scope.myMaxDate = new Date();

<!-- HTML -->
<input datepicker-popup="MM/dd/yyyy" max-date="myMaxDate" />

I don't understand why in this case the max-date attr takes a string rather than an expression like {{myMaxDate}}. How is it getting a hold of the actual value?

What's more, I'm using a decorator to alter some data from this directive and would like to access this attribute but all I get is the string myMaxDate.

    $provide.decorator("datepickerPopupDirective", ["$delegate", function($delegate) {
        // get references to the directive and old link function
        var directive = $delegate[0];
        var link = directive.link;

        // create a new link function using compile
        directive.compile = function() {
            // the new link function we want to return
            return function(scope, element, attrs, ngModelCtrl) {
                console.log(attrs.maxDate); // 'myMaxDate'

                // invoke the old link function
                link.apply(this, arguments);
            };
        };

回答1:

To answer your question on how the datepicker-popup directive finds the actual value of the max-date attribute, it most likely uses the $eval method of the scope.

So in your code, to see the actual value use:

 console.log(scope.$eval(attrs.maxDate));

This is also why the directive doesn't require double curly brackets. In fact double curly brackets will cause problems because it will convert your myMaxDate object to a string and consequently lose the Date object's methods.

For more information on the $eval method look at the AngularJS Scope API



回答2:

For starters you're overriding compile in its entirety. That would create potential problems.

 $provide.decorator("datepickerPopupDirective", ["$delegate", function($delegate) {
        // get references to the directive and old link function
        var directive = $delegate[0];
        var compile = directive.compile;

        directive.compile = function() {

            var link = compile.apply(this, arguments); 

            // the new link function we want to return
            return function(scope, element, attrs, ngModelCtrl) {
                console.log(attrs.maxDate); // 'myMaxDate'

                // invoke the old link function
                link.apply(this, arguments);
            };
        };

....