如何将此代码集成到我的AngularJS应用程序中?

时间:2014-06-30 18:18:22

标签: javascript angularjs controller integration

我正在学习AngularJS,同时构建一个使用它作为核心库的小应用程序,以及用于Bootstrap插件的jQuery。

我修改了网络上的一些示例以满足我的需求。现在它正在读取客户端文本文件并显示其内容。这是代码:http://plnkr.co/edit/qBVHM6?p=preview

现在,我想将它集成到我现有的Angular应用程序中来读取一些数据而不是使用虚拟JSON对象,但app的结构有点不同,我不知道如何将它们放在一起。

以下是我的HTML中的相关代码段:

<html ng-app="DrillApp">
    <head>
        <!-- jQuery + Bootstrap -->
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
        <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>

        <!-- AngularJS -->
        <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.18/angular.min.js"></script>
        <script src="res/controller.js"></script> <!-- my main controller -->
        <script src="res/localfile.js"></script> <!-- code from upload.js in Plunker demo -->
    </head>
    <body ng-controller="DrillController as drill">
        <input type="file" id="dbSelector" read-text="onFileSelect($files)">
        <p>{{drill.text}}</p>
    </body>
</html>

这是controller.js:

(function() {

    var app = angular.module('DrillApp', []).controller('DrillController', function() {
        this.isSupported = window.File && window.FileList && window.FileReader;

        this.questions = [
            /* list of dummy data which should be parsed from text files instead */
        ];

        /* ... some app logic removed for clarity ... */

        // function copied from app.js in Plunker demo hoping it would Just Work (tm)
        var getTextFile = function () {
            fileReader.readAsText(this.selectedFile, this).then(function(result) {
                this.text = result;
            });
        };

    });

    app.directive('readText', function() {
        return {
            link: function(scope, element) {
                element.bind('change', function(e) {
                    scope.selectedFile = (e.srcElement || e.target).files[0];
                    scope.getTextFile();
                });
            }
        };
    });

})();

localfile.js刚刚从Plunker重命名为upload.js.

选择文件后,运行此应用会导致以下错误:

Uncaught TypeError: undefined is not a function | controller.js:26
(anonymous function)                            | controller.js:26
m.event.dispatch                                | jquery.min.js:3
r.handle                                        | jquery.min.js:3

或jQuery和Bootstrap插件注释掉:

Uncaught TypeError: undefined is not a function | controller.js:26
(anonymous function)                            | controller.js:26
(anonymous function)                            | angular.js:2816
q                                               | angular.js:320
c                                               | angular.js:2815

我怀疑错误信息的区别并不重要。

虽然我相信我理解我自己的代码中发生的事情以及所有内容是如何链接在一起的,但我不知道该示例是如何工作的 - 因此我无法正确地集成它。

首先,我试图通过弄清AngularJS website中的例子来学习Angular,但我遇到了一些困难,所以我拿了CodeSchool course。它使用了稍微不同的方法,我更喜欢它,因为它是明确的(PEP 20应该适用于这里,对吗?)与所有控制器的东西。首先我定义它,然后别名并使用它,简单。

该演示使用了不清楚的语法。控制器被定义为具有适当名称的函数,然后在没有别名的情况下使用。我假设Angular在幕后发挥其魔力并且发现UploadController函数包含UploadController的逻辑。

我的问题是:

  1. 使用函数名称的显式.controller(...)语法和“hocus-pocus”语法之间是否存在任何功能差异?它们之间的切换会影响Angular的逻辑吗?

  2. 使用我首选的.controller()语法时,我可以使用this来更改范围。在替代语法中,范围通过参数显式提供,以及fileReader的实例(通过名称?Related question神奇地注入)。如果我只是用scope关键字替换this的所有引用并注入fileReader,就可以了:

    .controller('DrillController', ['fileReader', function(fileReader) { //...
    
  3. 导致该错误的原因是什么?看起来该指令没有得到我的控制器所做的相同的上下文。为什么它在演示中有效,但在我的应用中却没有?它是由使用显式控制器语法引起的吗?

1 个答案:

答案 0 :(得分:1)

好的,你遇到的问题就在这里。

var getTextFile = function () {
            fileReader.readAsText(this.selectedFile, this).then(function(result) {
                this.text = result;
            });
        };

你应该这样做

 $scope.getTextFile = function () {
                fileReader.readAsText(this.selectedFile, this).then(function(result) {
                    this.text = result;
                });
            };

如果要使用原始范围中的getTextFile。否则,您将创建一个名为getTextFile的变量,该变量在初始化之外无法访问。

解释您的错误:

scope.getTextFile();

该代码正在查找范围对象上的getTextFile变量。这是未定义的。由于它未定义,因此无法像函数一样调用它。

你的控制器也需要接受一个$ scope变量,你需要在$ scope上设置你想要的东西而不是这个。

.controller('DrillController', function($scope) {
$scope.GetText = function(){};
})