AngularJS将javascript对象绑定到指令属性

时间:2015-12-03 16:23:03

标签: javascript angularjs

当我尝试在指令的属性中绑定javascript对象时,我遇到了问题。

我有一个控制器,我在其中向rest api服务发出$ http.get请求,我收到一些数据,其中一个JSON字符串表示地图画布的行程。

.controller('myController', ['$scope', '$http', function($scope,$http) {
    $http.get(endpointUrl)
        .success(function(data){
            if(data.status == 'ok'){
                $scope.itinerary = angular.fromJson(data.itinerary);
            }
        });
}]);

如果我在控制台中记录$ scope.itinerary,我发现它是一个有效的javascript对象

{"origin":"Piazza Adua, Firenze","destination":"Galleria degli Uffizi, Firenze","waypoints":[{"location":"Fiesole, Firenze","stopover":true},{"location":"Piazza Santa Croce, Firenze","stopover":true}],"optimizeWaypoints":false,"travelMode":"DRIVING"}

我需要在指令属性中绑定该对象。

.directive('map', function(){
    return {
        restrict: 'E',
        scope: {
            myItinerary: "="
        },
        templateUrl: 'templates/directive/map.html',
        link: function(scope,el,attrs) {
            console.log(attrs);
        }
    }
});

这是HTML

<map my-itinerary="itinerary"></map>

当我在指令链接函数中记录attrs时,属性myItinerary是字符串“itinerary”,而不是像我期望的那样的对象。 我尝试使用{{}}插入行程,但正如我所料,这会生成语法错误。 我还试图用'@'切换'='并绑定json字符串而不是javascript对象,但指令内的attrs.myItinerary值是一个空字符串。 我看到很多例子将一个对象绑定到一个指令,没有人对我使用的相同方法有问题。 自从我最近开始使用角度以来,我想知道我的方法是错误的还是为什么它不起作用。 在此先感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

我为hypen(-)指令创建了sample

您必须确保使用

scope: { 
   myItinerary: "=myItinerary"
}

您可以参考angularjs

Creating a Directive that Wraps Other Elements部分下的最后一个示例

答案 1 :(得分:0)

原始问题

将某些内容绑定到指令时,$scope对象上的绑定值可用。不是attrs对象。

所以在控制器$scope.controllerParam = 10

并在视图<my-directive input="controllerParam"></my-directive>

中实施

你可以有一个像这样的指令标记

.directive('myDirective', function () {
    return {
        restrict: E,
        scope: {
            input: '='
        },
        link: function ($scope, e, attrs) {
            console.log($scope.input); //Will log 10
            console.log(attrs.input); //Will log string controllerParam
        }
    }
});

更新链接中的内容

这来自您对来自API的数据的评论。

首次运行指令时,链接功能会运行一次。这就是为什么当你在console.log你的作用域时,值myItinerary是未定义的,因为此时AJAX调用还没有返回。如果你将console.log置于超时状态,它将在AJAX请求返回时起作用,并且在此时通过数据绑定更新值。然而,处理这样的动态内容是一个糟糕的主意。

<强>观看

如果您需要在链接功能中执行绑定变量的某些逻辑,您可以在其上放置一个监视器,以便在指令内部或外部更改时,您的监视处理程序将会触发。

$scope.$watch('myItinerary', function(newValue, oldValue) {
  console.log(newValue, oldValue);
});

然而,如果您添加大量这些产品会因性能问题而受到影响,因为每次运行摘要周期时都会对每个手表进行评估,因此可能很难处理这些事实,这些事实可能会从指令内部或外部的变化中触发用。

<强>服务

一般来说,所有的ajax请求都应该在服务中定义并注入到需要它们的内容中。因此,如果指令具有单一目的,则可以通过将服务直接注入其中来实现该请求。

绑定功能 您的指令可能还会暴露控制器可以绑定的函数。当您的控制器有数据时,它可以调用此函数传递数据。

//View
<my-directive update="update"></my-directive>

//in controller simply do
$scope.update('new data');

//directive

.directive('myDirective', function () {
    return {
        restrict: E,
        scope: {
            update: '='
        },
        link: function ($scope, e, attrs) {
            $scope.update = function (d) {
                console.log(d);
            }
        }
    }
});

如果您尝试调用尚未更新的绑定函数或者指令将其作为可选项,则必须小心。在任何一种情况下,控制器中的绑定变量都是未定义的。

在我看来,所有这些服务都是最好的。当服务不合适时,回到手表。我避免暴露功能,因为它只是让我觉得不对,但它可能。为了公平起见,我很少需要在我必须做的事情中使用手表。

对于论文感到抱歉