【问题标题】:create an angularjs directive to wrap jquery tagcanvas plugin创建一个 angularjs 指令来包装 jquery tagcanvas 插件
【发布时间】:2016-08-14 20:26:21
【问题描述】:

我想实现一个动画词云。由于我没有找到任何 angular 或 Ionic 插件来做我想做的事,我决定(而且我发现学习很有趣)为 jquery 代码创建一个 angular 包装器。 插件为tagcanvas,使用示例为this

到目前为止我做了什么:

  • 我将 jquery js 文件添加到我的 index.html 中
  • 我在声明指令的地方创建了一个 js 文件,并将其添加到 index.html:

tagcanvas.js

angular.module('tagCanvas', [])

.directive('tagCanvas', function() {

return {

  restrict: 'E',
  link: function (scope, element, attrs) {


        element.tagcanvas({


            outlineColour: attrs.outlineColour,
            reverse: attrs.reverse,
            depth: attrs.depth,
            maxSpeed: attrs.maxSpeed,
            textFont: attrs.textFont,
            textColour: attrs.textColour,
            weightMode: attrs.weightMode,
            weight: attrs.weight
        }, attrs.canvas);



  }
};

});

正如您在 codepen 示例中看到的,我需要调用一些属性,以及一个 html 元素 id canvas,我不知道如何在我的指令中调用它们。

我的第二个问题是我不知道如何创建和调用要在我的标签云中显示的单词。 我看了很多教程,但我仍然不知道该怎么做。任何帮助将不胜感激。

【问题讨论】:

    标签: javascript jquery html angularjs ionic-framework


    【解决方案1】:

    首先,我不会用相同的名称命名您的 Angular 应用程序和指令。它不仅令人困惑,而且可能无法正常工作。其次,虽然可能有很多方法可以解决这个问题,但我会这样做:

    指令
    (我已将指令更改为属性而不是元素,并为属性使用了隔离范围。链接函数包含在 $timeout 中,以确保在尝试调用 tagcanvas 之前元素存在于 DOM 中。)

    .directive("tagCanvas", function($timeout) {
        return {
            restrict: "A",
            scope: {
                canvasId: "@",
                outlineColour: "@",
                reverse: "@",
                depth: "@",
                maxSpeed: "@",
                textFont: "@",
                textColour: "@",
                weightMode: "@",
                weight: "@"
            },
            link: function (scope, element) {
                $timeout(function() {
                    element.tagcanvas({
                        outlineColour: scope.outlineColour,
                        reverse: scope.reverse,
                        depth: scope.depth,
                        maxSpeed: scope.maxSpeed,
                        textFont: scope.textFont,
                        weightMode: scope.weightMode,
                        weight: scope.weight
                    }, scope.canvasId);
                });
            }
        };
    })
    

    控制器
    (您可能希望从服务或其他存储中获取您的单词列表,但为了说明,我在控制器中硬编码了一个数组)

    .controller("ctrl", function ($scope) {
        $scope.wordList = [
            {
                href: "#",
                fontSize: "2.83ex",
                text: "1000"
            }, {
                href: "#",
                fontSize: "4.8ex",
                text: "example"
            }, {
                href: "#",
                fontSize: "8.77ex",
                text: "gif"
            }, {
                href: "#",
                fontSize: "2.83ex",
                text: "svg"
            }, {
                href: "#",
                fontSize: "8.77ex",
                text: "jpg"
            }, {
                href: "#",
                fontSize: "10.68ex",
                text: "png"
            }, {
                href: "#",
                fontSize: "2.83ex",
                text: "bmp"
            }, {
                href: "#",
                fontSize: "4.8ex",
                text: "img"
            }
        ];
    })
    

    html

    <div>
        <canvas width="300"
                height="300"
                id="myCanvas"
                tag-canvas
                canvas-id="tags"
                outline-colour="#ff00ff"
                text-font="Arial"
                text-colour="#ff00ff"
                reverse="true"
                depth="0.8"
                max-speed="0.05"
                weight-mode="both" 
                weight="true"></canvas>
    </div>
    <div id="tags" style="font-size: 50%;">
        <a ng-repeat="word in wordList" href="{{word.href}}" style="font-size: {{word.fontSize}}">{{word.text}}</a>
    </div>
    

    【讨论】:

    • 我有一个错误说'tagcanvas'函数不是一个函数,虽然我确保添加了jquery.tagcanvas.js和tagcanvas.js:/
    • 您一定引用了错误的内容。这是working Plunker,其中包含我的答案中的确切代码。
    • 控制器有问题。我不明白在哪里声明它。因为我有一个名为 starter.Clients 的模块和一个名为 clientsController 的控制器,所以我想在其中使用 tagCloud (clients.html)。那么我需要调用'ctrl'控制器而不是你在clientsController中创建的控制器吗? :/ 我很困惑。
    • 我不明白你的问题。为方便起见,我在我提供的演示中使用了appctrl。除了存储单词列表之外,控制器与您的问题无关,因此您不必更改代码中的任何内容。我只是展示了如何将 tagcanvas 包装在指令中 - 如何获取单词列表、它们各自的大小和 href,然后将它们输出到 tagcanvas 可以使用的 div 中,这是对问题的一种辅助,并且可能非常具体到你的实现。
    【解决方案2】:

    我制作了一个带有工作示例的示例 plunker,您可以在其中动态添加新标签: http://plnkr.co/edit/zR4pxcZlqPxr8pnhsNRI?p=preview

    在 AngularJS 指令中使用 tagcanvas 并不容易。 Tagcanvas 严重依赖特定的 DOM 表示。这有时会与 AngularJS 的工作方式不一致。因此,我不得不使用$timeout 服务。

    最好用你的 tagcanvas 指令制作一个“组件”,它本身负责它的 HTML。

    app.directive('tagCanvas', function($timeout) {
    
      return {
        scope: {
          tagData: '='
        },
        controllerAs: 'vm',
        template: '<canvas width=300 height=300" id="my-canvas"></canvas>' +
        '<div id="tags"><a ng-repeat="tag in tagData" ng-bind="tag.name"></a></div>',
        restrict: 'E',
        link: function(scope, element, attrs) {
            element.find('canvas').tagcanvas({
              outlineColour: '#ff00ff',
              reverse: true,
              depth: 0.8,
              maxSpeed: 0.05,
              textFont: null,
              textColour: null,
              weightMode: 'both',
              weight: true
            }, 'tags');
    
            scope.$watch('tagData', function(newValue) {
              $timeout(function() {
                element.find('canvas').tagcanvas('reload');
              }, 0);
            }, true);
        }
      };
    
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-03
      • 2014-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多