javascript - 为什么要将 D3 源代码复制到 Angular 服务中?

标签 javascript angularjs svg d3.js

我尝试将 d3 用于 Angular 项目,如 ng-newsletter 上的主要示例之一所述。 .其中展示了如何在 Angular 内设置 D3 服务。

我想知道如何将 D3 作为 Angular 服务包含在 Angular yeoman 和 bower 中?还是我怀疑下面存在冲突?

看来我需要该服务才能将 D3 服务注入(inject)我的指令。否则,在尝试通过脚本标记将 d3 库包含到全局空间时,我的 Angular 指令无法引用 D3 对象。

我担心使用 D3 作为 Angular 服务会降低代码的性能,而这些代码是通过使用 yeoman/grunt/bower 的一些最佳实践获得的。例如缩小代码,使用 Bower 更新到 D3 的 future 版本。

最佳答案

我明白你的意思。如果您使用 bower,则 D3 会在全局范围内初始化。遵循 ng-newsletter 上描述的方法将为您提供一个 D3 实例作为服务,但您必须在 bower 之外管理它。

AngularJS 中服务的全部意义在于对象在需要时被初始化。因此,我选择的技术是一种妥协。它与 Yeoman Angular 生成器和 Bower 一起工作,并将 D3 放入 Angular 服务中。然而,该服务实际上只是引用了 window.d3 对象,因此 AngularJS 的纯粹主义者可能会认为它是 hacky。

首先,使用 bower 安装 D3:

bower install d3 --save

您的 bower.json 文件将更新为如下所示:

{
  "name": "[YOUR_APP]",
  "version": "0.0.0",
  "dependencies": {
    "angular": "^1.3.0",
    "bootstrap-sass-official": "^3.2.0",
    "angular-animate": "^1.3.0",
    "angular-cookies": "^1.3.0",
    "angular-resource": "^1.3.0",
    "angular-route": "^1.3.0",
    "angular-sanitize": "^1.3.0",
    "angular-touch": "^1.3.0",
    "d3": "~3.5.5"
  },
  "devDependencies": {
    "angular-mocks": "^1.3.0"
  },
  "appPath": "app",
  "moduleName": "[YOUR_APP]"
}

请注意 D3 现在在那里 - "d3": "~3.5.5"。

当您执行“grunt serve”以查看 http://localhost:9000 上的站点时, D3 现在将包含在全局范围内。此外,当您执行“grunt 构建”时,它将与所有其他 javascript 一起被缩小和丑化并复制到/dist 目录。

到目前为止还不错,但它是在全局范围内,而不是在它应该在的 AngularJS 服务中。

编写服务很简单。在您的 app.js 中,添加以下内容:

angular.module('d3Module', []).factory('d3', [
  function(){

    var d3;
    d3 = window.d3;

    // returning our service so it can be used
    return d3;
}]);

也许这不是返回 d3 的绝对最佳方式。也许应该按照本文底部的建议使用 module.exports 来完成 - http://lorenhoward.com/blog/simple-way-integrate-d3-angular/ .我对 AngularJS 不是很熟悉,所以我可能遗漏了一个细微差别。

无论如何,只需将“D3Module”添加到您应用的模块列表中即可:

var app = angular
  .module('[YOUR_APP]', [
    'ngAnimate',
    'ngCookies',
    'ngResource',
    'ngRoute',
    'ngSanitize',
    'ngTouch',
    'd3Module'
  ])
  .config(function ($routeProvider) {

    // eg. Some rout stuff

  });

服务“d3”现在可以包含在指令中:

app.directive('ngLogo', ['d3', function(d3) {
  return {
    restrict: 'A',
    scope: {},
    link: function(scope, element) {

    // Do some SVG stuff, eg:
    var svg = d3.select(element[0]).append('svg');

    }};
  }]);

关于javascript - 为什么要将 D3 源代码复制到 Angular 服务中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22434742/

相关文章:

javascript - Angular promise 返回 "undefined"值 .NET MVC

javascript - 如何将属性 `preserveAspectRatio` 添加到 Highchart svg

javascript - 位置固定元素上的 Jquery 委托(delegate)滚动事件

javascript - 将“加载更多”添加到使用 $.getJSON 从 Google 电子表格接收的数据输出中

javascript - 语义 UI 转换不适用于 jQuery 数组对象

javascript - 使用带有静态文件而不是服务器的 Karma 进行 AngularJS 端到端测试

javascript - 悬停链接需要双击

javascript - 在angular js中使用表达式作为ng类

image - 如何在网页中使用 .svg 文件?

javascript - 制作一个已知边两条垂直线位置的矩形(路径元素)