简体   繁体   中英

How to render scope variable on template in Angular directive

[UPDATE] It turns out that if I use "@" as scope variable, it will be used in a async way when render template( I still can not figure out why and how ), the order will be compiple -> controller -> pre ->post ->observe, the strange thing is until POST stage, the scope.data still object, but inside the observe, it suddenly become string, could any one give me some help about why this happen( like when the template get data bind to it)?

var app = angular.module("vp", []);
app
.controller("main", function($scope){
    $scope.data = ["1", "2"];
})
.directive("chartBuilder", function(){
    return {
        restrict: "AE",
        scope: {
            data: "@data"
        },
        controller: function($scope){
            console.log($scope.data);
            $scope.data = JSON.parse($scope.data);
        },
        template: '<div><input ng-repeat="d in data track by $index" ng-model="data[$index]" /></div>',
        compile: function(EL, attrs){
            console.log(EL);
            return {                    
                pre: function(scope, EL, attrs){
                    console.log(scope.data);
                },
                post: function(scope, EL, attrs){
                // link: function(scope, EL, attrs){
                    console.log(scope.data);
                    attrs.$observe("data", function(d){
                        console.log(d);
                        scope.data = JSON.parse(scope.data);
                        console.log(d);
                    })
                }
            }
        }
    };
});

All:

I am pretty new to Angular directive, say I have a directive which accept attr from parent scope:

<html ng-app="vp">
<head>
    <title></title>
</head>
<body ng-controller="main">

    <input ng-repeat="d in data track by $index" ng-model="data[$index]" />

    <chart-builder data={{data}}></chart-builder>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
    <script type="text/javascript">
        var app = angular.module("vp", []);
        app
        .controller("main", function($scope){
            $scope.data = ["1", "2"];
        })
        .directive("chartBuilder", function(){
            return {
                restrict: "AE",
                scope: {
                    data: "@"
                },
                controller: function($scope){
                    $scope.data = JSON.parse($scope.data);
                },
                template: '<div><input ng-repeat="d in data track by $index" ng-model="data[$index]" /></div>',
                link: function(scope, EL, attrs){
                }
            };
        });
    </script>

</body>
</html>

Notice that I use "@" in directive, the reason is I want to set logic like :

The parent scope can affect the value in directive, but in directive, it is only allowed to copy the data from parent scope and any change inside it can not reflect to parent scope.

So for example, the init parent scope data is [1,2], so the directive will get that as string(because @), and in controller, turn it into object, then render on the template.

But the thing is:

The data in directive is still a string when rendered on template , I wonder why the JSON.parse not work( in the controller of directive, It does work, but when bind to template, it still string )

Thanks

Much simpler to just pass in the array reference:

<chart-builder data="data"></chart-builder>

JS

 app
    .controller("main", function($scope){
        $scope.data = ["1", "2"];
    })
    .directive("chartBuilder", function(){
        return {
            restrict: "AE",
            scope: {
                data: "="
            },
            controller: function($scope){
                console.log($scope.data)// array not string ["1", "2"]  
            },
            template: '...',
            link: function(scope, EL, attrs){
            }
        };
    });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM