如何使用 angularJS 模板将一些 HTML 代码添加到 DOM 并使 AngularJS 插入它们?

How to add some HTML code to the DOM with angularJS templates and make AngularJS to interpolate them?

我有一些服务。我想调试它并查看此服务中变量的状态。我的代码如下(代码下方的解释):

module.factory('Data', function () {
    var current = [], unlocked = [], all = [];

    return {
        current: current,
        unlocked: unlocked,
        total: all
    }
});
module.controller('debugPlaneController', ['$scope', 'Data', function ($scope, data) {
    $scope.data = data;
}]);
module.factory('someService', ['Data', function (data) {
    var initDebugMode = function () {
        var style = "style='width: 500px; height: 100px; background-color: #ccc;";
        var template = "
            <div "+style+" ng-controller='debugPlaneController'>
                <p>data.current = {{ data.current }}</p>
                <p>data.total = {{ data.total }}</p>
                <p>data.unlocked= {{ data.unlocked }}</p>
            </div>
        ";
        $(".someClass > .childClassOfSomeClass").append(template);
    };
    // some more methods, for example
    var push = function (name) {
        data.current.push(name);
        data.all.push(name);
    }
    // etc
    return {
        initDebug: initDebugMode,
        push: push
        // some more methods
    }
}]);

module.controller('mainController', ['$scope', 'someService', function($scope, someService) {
    someService.initDebug();
    someService.push('lala');
});

所以,我有一些带控制器的应用程序 mainController。我想在其中使用服务someService。我正在使用 push 方法。此方法将数据从 name 参数推送到数据服务 Datatotalcurrent 数组。如您所见,我从 mainController 调用了方法 initDebug(),所以我希望调试 window 出现在我的屏幕上。我想显示 Data 数据服务的数组 currenttotalunlocked 的状态。

实际上,window 出现在屏幕上,但我在上面看到了这个:

data.current = {{ data.current }}
data.total = {{ data.total }}
data.all = {{ data.all }}

因此,AngularJS 模板未被插入。我如何让它们插值 + 我需要在这个块中实时更新它们(就像 angularJS 实际上做的那样)。

更新

使用 $compile.

所以我需要这样更改我的 initDebugMode 功能?:

module.factory('someService', ['Data', '$compile', function (data, $compile) {
    var initDebugMode = function () {
        var style = "style='width: 500px; height: 100px; background-color: #ccc;";
        var scopeImitation = { data: data };

        var template = "
            <div "+style+" ng-controller='debugPlaneController'>
                <p>data.current = {{ data.current }}</p>
                <p>data.total = {{ data.total }}</p>
                <p>data.unlocked= {{ data.unlocked }}</p>
            </div>
        ";
        $compile(template)(scopeImitation);
        $(".someClass > .childClassOfSomeClass").append(template);
    };
// etc...
]);

$compile 服务中如何将变量传递到第二个括号?我用对了吗?

您需要使用$编译服务:

$编译

Compiles an HTML string or DOM into a template and produces a template function, which can then be used to link scope and the template together.

你会像这样使用它:

$compile(template)($scope);

别忘了先将 $compile 服务和 $scope 注入你的工厂。

我还会通读此 post 以了解您可以用来实现目标的其他 angular 服务:

What is the difference between the $parse, $interpolate and $compile services?

因为$interpolate可能更适合你要做的事情,但$compile是最强大的。


关于您的修改

起初我并没有真正注意到你在工厂里。我认为将作用域传递给工厂通常是不可取的(也许不可能?)。如果你想要一个可重用的调试接口,我认为最好的方法不是把它放在你的工厂里,而是做一个指令:

module.directive('debug' , function() {
    return {
        restrict: 'E',
        template:'<div><p>data.current = {{ data.current }}</p><p>data.total = {{ data.total }}</p><p>data.unlocked= {{ data.unlocked }}</p></div>',
        controller: 'debugPlaneController'
    }
});

我从您的模板中删除了 style,因为您实际上可以通过为 debug

定义 css 规则来设置 css 指令的样式
debug > div {
    width: 500px;
    height: 100px;
    background-color: #ccc;
}

我从您的模板中删除了 ng-controller,因为您的指令将使用指令中定义的控制器。

现在你可以像这样把你的指令放在任何你想要的地方。它会在内部正确生成模板,您不必担心 $compile:

<debug></debug>

此外,如果您只想有条件地显示它,您可以使用 ng-if

<debug ng-if="debugMode == true"></debug> //debugMode would be a variable you defined in your controller

另外关于您对 $compilescopeImitation 的问题,我以前从未见过它以这种方式使用,我认为这不会起作用。 $compile 从我看到的总是写成 $compile(thing to compile)($scope)