【问题标题】:Why isn't my dynamically created element not showing up?为什么我的动态创建的元素没有显示?
【发布时间】:2018-08-01 12:20:37
【问题描述】:

好的,所以我创建了一个未硬编码的聊天小部件,而是由服务创建的,例如:

$chatWidget.setParent(parent).setUser(user).setMessages(messages).build();

这里是$chatWidget服务的构建函数:

var build = function () {
        if (parentElement && myUser && myMessages) {
            parentElement.append('<re-chat></re-chat>');
        }
    }

这是聊天指令的简化版本:

    angular
    .module('app')
    .directive('reChat', function ($chatWidget) {
        return {
            restrict: 'E',
            replace: true,
            template: 

    '<div id="chat-widget-container"><div id="chat-widget-header">reUser.name</div>'+
    '<div id="chat-widget-body"<div ng-repeat="message in reMessages"><div>' +
    '<p> {{message.body}} </p></div></div></div>' +
      '<textarea ng-model="messageToSend" id="message-to-send" placeholder ="Type your message" rows="3"></textarea>' +
      '<button class="btn btn-default">Send</button></div>',
            scope: {
                reMessages: '=',
                reParent: '<',
                reUser: '<'
            },
            link: function (scope, element, attrs) {    
            scope.reUser = $chatWidget.getMyUser();
            scope.reMessages = $chatWidget.getMyMessages();
            scope.reParent = $chatWidget.getParent();
        };
    });

问题来了

我的 re-chat 指令出现在 DOM 结构中,但其内部 html 完全为空。

我尝试了几种替代方法,包括删除模板并执行此操作:

var html = '[TEMPLATE HERE]' 
element.html(html);
$compile(element.contents())(scope);

或:

var html = '[TEMPLATE HERE]';
element.replaceWith(html);

两者都无济于事。 那么,我怎样才能让我的指令的 html 显示出来???

编辑

如果我像下面这样硬编码,小部件看起来很好:

<re-chat re-messages="messages" re-my-user="user"></re-chat>

但这不是我想要的行为。我希望动态添加指令。

【问题讨论】:

  • @JCFord 服务方法只是基本的 getter 和 setter,它们似乎工作正常。有趣的是,当我以动态方式执行时,指令中的链接函数似乎根本没有执行。

标签: angularjs dom angularjs-directive angularjs-scope angularjs-compile


【解决方案1】:

尝试更改您的指令以使用共享范围并摆脱链接功能。

然后在您的服务build() 方法中创建一个新的子范围。将指令的数据附加到新的子范围。然后用子作用域编译新指令并将其附加到 DOM。

var build = function () {
    if (parentElement && myUser && myMessages) {
        var childScope = scope.$new(); //pass true here if you want to
                                       //inherit parent scope properties.
        childScope.reMessages = myMessages;
        parentElement.append($compile('<re-chat></re-chat>')(childScope));
    }
}

【讨论】:

  • 我的构建功能在我的工厂。据我所知,我无法从工厂访问范围。我希望聊天小部件独立于任何视图或控制器。
  • 您通常不应该将$scope 注入到服务中,但是您可以将它从控制器传递到服务函数中。调用时将作用域对象传递给.build()
  • Angular 永远不会编译你的指令,除非你告诉它。您可以通过将指令添加到将被编译的模板或通过注入$compile 服务并自己调用它来做到这一点。如果你的 build() 函数是你想要创建 &lt;re-chat&gt;&lt;/re-chat&gt; 元素的地方,那么你需要针对那里的范围对象编译它。
  • 现在完美运行,我会接受您的回答并非常感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-11-14
  • 1970-01-01
  • 2022-08-16
  • 1970-01-01
  • 2016-03-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多