javascript - 在 Selectize.js 项目中呈现 Angular Directive(指令)

标签 javascript angularjs angular-directive selectize.js

我正在使用 angular-selectize使用Selectize.js在我的 Angular 项目中。

要在 Selectize.js 选择器中使用自定义项,我使用 Selectize.js 的 render选项:

render: {
  item: function(item, escape) {
    var avatar = '<div>' +
        '<span avatars="\'' + escape(item._id) +'\'" class="avatars">' +
        '</span>' +
        escape(item.nick) +
      '</div>';
    var compiledAvatar =  $compile(avatar)($rootScope);
    $timeout();
    return compiledAvatar.html();
  },

其中 avatars 是具有异步行为的自定义指令

问题是 render.item 函数需要一个 HTML 字符串作为输出但是:

  • 无法像 render.item 方法那样以同步方式返回呈现的或“$compileed”HTML 字符串。
  • 当项目的元素已添加到 DOM 中时,我不知道如何在之后呈现该项目的元素。

注意虽然调用了$compile,但由于$compile的异步特性,返回的字符串不是预期的编译结果,而是编译前的字符串。

最佳答案

一个想法是使用 DOM 操作,这不是 Angular 最推荐的方式,但我明白了 working on this plunker.和一个 second one with custom directive and randomized data to simulate your compiled avatar.

为了模拟您的异步调用,我使用了 ngResource。我的渲染函数返回一个字符串 "<div class='compiledavatar'>Temporary Avatar</div>"带有特殊的类标记 compiledavatar .在一两秒钟内,您会在选择一个元素时看到临时头像。当 ngResource 调用完成时,我查找类为 compiledavatar 的元素然后将 html 替换为我下载的内容。这是完整的代码:

var app = angular.module('plunker', ['selectize', 'ngResource']);

app.controller('MainCtrl', function($scope, $resource, $document) {
  var vm = this;
  vm.name = 'World';
  vm.$resource = $resource;
  vm.myModel = 1;
  vm.$document = $document;

  vm.myOptions = [{
    id: 1,
    title: 'Spectrometer'
  }, {
    id: 2,
    title: 'Star Chart'
  }, {
    id: 3,
    title: 'Laser Pointer'
  }];

  vm.myConfig = {
    create: true,
    valueField: 'id',
    labelField: 'title',
    delimiter: '|',
    placeholder: 'Pick something',
    onInitialize: function(selectize) {
      // receives the selectize object as an argument
    },
    render: {
      item: function(item, escape) {
        var label = item.title;
        var caption = item.id;
        var Stub = vm.$resource('mydata', {});
        // This simulates your asynchronous call

        Stub.get().$promise.then(function(s) {
          var result = document.getElementsByClassName("compiledavatar")
          angular.element(result).html(s.compiledAvatar);

          // Once the work is done, remove the class so next time this element wont be changed
          // Remove class
          var elems = document.querySelectorAll(".compiledavatar");
          [].forEach.call(elems, function(el) {
              el.className = el.className.replace(/compiledavatar/, "");
          });

        });

        return "<div class='compiledavatar'>Temporary Avatar</div>"
      }
    },
    // maxItems: 1
  };
});

为了模拟 JSON API,我刚刚在 plunker 中创建了一个文件 mydata :

{
    "compiledAvatar": "<div><span style='display: block; color: black; font-size: 14px;'>an avatar</span></div>"
  }

当然,你的编译函数应该在每次调用时返回不同的东西。我用同样的方法来证明这个原理。

另外,如果你的动态代码是一个 Agular 指令,这里是一个 second plunker使用自定义指令和随机数据,以便您可以更好地查看解决方案:

数据包括自定义指令 my-customer :

[{
    "compiledAvatar": "<div><span style='display: block; color: black; font-size: 14px;'>an avatar  #1  <my-customer></my-customer></span></div>"
  },
  {
    "compiledAvatar": "<div><span style='display: block; color: black; font-size: 14px;'>an avatar  #2  <my-customer></my-customer></span></div>"
  },
(...)

指令定义为:

app.directive('myCustomer', function() {
  return {
    template: '<div>and a custom directive</div>'
  };
});

应用程序的主要区别在于替换 HTML 时必须添加 $compile 并且文本应显示 An avatar #(number) and a custom directive .我得到一个 json 值数组,并使用一个简单的随机数来选择一个值。替换 HTML 后,我将删除该类,因此下次只会更改最后添加的元素。

 Stub.query().$promise.then(function(s) {
      var index = Math.floor(Math.random() * 10);
      var result = document.getElementsByClassName("compiledavatar")
      angular.element(result).html($compile(s[index].compiledAvatar)($scope));

      // Remove class
      var elems = document.querySelectorAll(".compiledavatar");
      [].forEach.call(elems, function(el) {
        el.className = el.className.replace(/compiledavatar/, "");
      });
});

另外,我查看了 selectize 库,你不能返回一个 promise... 因为它对 render 返回的值执行 html.replace。这就是为什么我去了一个带有类的临时字符串的路由,以便稍后检索和更新。 让我知道这是否有帮助。

关于javascript - 在 Selectize.js 项目中呈现 Angular Directive(指令),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38106412/

相关文章:

javascript - BrowserRouter v4 - 'BrowserRouter' 未定义 react/jsx-no-undef

javascript - 如何禁用 Angular 缓存

angularjs - Protractor 添加请求 header

javascript - Angular ng-repeat 需要更改从 json 获取的数据

jquery - 在 Angular 世界之外发生更改时如何更新 Angular 2 Reactive 表单字段

angularjs - CORS错误-获取$ compile错误和XMLHttpRequest无法加载错误?

javascript - 使用 Javascript 调用 Web 服务

javascript - 自定义选项更新 Magento 产品图像

javascript - 捕获相机并在 div 中显示预览

angularjs - 如何将标签的内容绑定(bind)到指令的范围内?