Angular $ compile / $ controller没有绑定范围到动态HTML

时间:2015-09-07 09:47:20

标签: javascript angularjs

正如标题所述,我正在尝试编译并将角度控制器链接到动态HTML。

我的目标是创建一个服务,它接受一组选项,其中一个是控制器,我可以在将它附加到DOM之前链接到动态HTML,然后这将为用户提供此服务访问该绑定控制器的$scope,并且可以选择覆盖范围,如果他们愿意的话。

我尝试使用$controller$compile服务,但由于某种原因,模板正在被追加,但是没有被处理,看起来似乎没有设置范围,因为一旦附加,它将显示模板标签,而不是实际值。

我应该使用$controller还是$compile,但不能同时使用?

我不完全确定我哪里出错了,一​​些指导会非常感激。

panel_template.html

<div class="pathwindow">
    <div class="pathwindow_title">
        <h1>{{ title }}</h1>
    </div>
    <div class="pathwindow_content">
        {{ content }}
    </div>
</div>

app.controller.js

(function () {
    'use strict';

    var appController = angular.module('app.controller', []);

    appController.controller('appController', ['$state', '$scope', '$rootScope', 'PanelService', function ($state, $scope, $rootScope, PanelService) {

        $scope.title = 'A Awesome Title';
        $scope.content = 'This is some content...';

        $scope.clickMe = function () {

            PanelService.show('panel_template.html', 'appController');

        };

    }]);

})();

app.factory.js

(function () {
    'use strict';

    var appFactory = angular.module('app.factory', []);

    appFactory.factory('PanelService', ['$injector', '$controller', '$compile', '$rootScope', '$http', function ($injector, $controller, $compile, $rootScope, $http) {

        var self = {};

        self.show = function (template_url, controller, scope) {

            var $scope = angular.isObject(scope) ? scope.$new() : $rootScope.$new();

            $http.get(template_url).then(function(response){

                var html = response.data;

                angular.element('#panels').append(html);

                $controller(controller, { $scope: $scope, $element: html });

                $compile(angular.element(html))($scope);

            });

        };

        return self;

    }]);

})();

1 个答案:

答案 0 :(得分:1)

您正在将已分离的元素传递给$compile,而不是通过将response.data附加到DOM创建的元素。语句后面会抛弃此元素。没有编译的response.data字符串附加到DOM,这就是您看到“未编译”模板的原因。

您将获得以下更多运气:

$http.get(template_url).then(function(response) {
    var elem = $compile(response.data)($scope);
    angular.element('#panels').append(elem);
    $controller(controller, { $scope: $scope, $element: elem });
});

这是令人恐惧的代码:编译后的元素应该被正确销毁吗?控制器是否被正确销毁?在$controller(...)语句之后控制器是否应用,或者它的引用是否丢失,因此它不再存在?

您必须检查这些,可能需要调整代码,例如听取$destroy事件和清理和/或保持对控制器的引用。

同样让我感到害怕的是,服务会像这样进行DOM操作。我很确定还有另一种方式(可能是ui-router的嵌套视图 - 但我不完全确定你的确切用例)。