简体   繁体   中英

How to integrate this code into my AngularJS app?

I'm learning AngularJS while building a little app which is using it as a core library, along with jQuery for Bootstrap plugins.

I've modified some example found on the web to suit my needs. Now it's reading client-side text files and displaying their contents. Here's the code: http://plnkr.co/edit/qBVHM6?p=preview

Now, I'd like to integrate it into my existing Angular app to read some data instead of using dummy JSON object, but app's structure is a bit different and I don't know how to put it all together.

Here's the relevant snippet from my 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>

Here's 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 is just renamed upload.js from Plunker.

Running this app results in following error after selecting a file:

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

or with jQuery and Bootstrap plugins commented out:

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

I suspect the difference in error messages doesn't matter.

While I believe I understand what's going on in my own code and how everything is linked together, I don't get how the example works - thus I'm unable to integrate it correctly.

First I've tried to learn Angular by figuring out what happens in examples from AngularJS website , but I ran into some difficulities, so I took the CodeSchool course . It was using slightly different approach which I liked more, because it was explicit ( PEP 20 should apply here, right?) with all the controller stuff. First I define it in, then alias it and use it, simple.

The demo uses that unclear syntax. The controller is defined as a function with appropriate name and then used without aliasing. I assume that Angular does its magic behind the scenes and figures out that UploadController function contains logic for UploadController.

My questions are:

  1. Is there any functional difference between explicit .controller(...) syntax and "hocus-pocus" syntax that uses function name? Will switching between them affect Angular's logic?

  2. When using my preferred .controller() syntax I can use this to alter the scope. In the alternative syntax the scope is provided explicitly via arguments, along with an instance of fileReader (magically injected by name? Related question ). Is it fine if I simply replace all references to scope with this keyword and inject fileReader like this:

     .controller('DrillController', ['fileReader', function(fileReader) { //... 
  3. What causes that error? It looks like the directive doesn't get the same context that my controller does. Why does it work in the demo, but not in my app? Is it caused by using explicit controller syntax?

Ok, The problem you are running in to is right here.

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

You should be doing

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

if you want to use the getTextFile from your original scope. Otherwise you are creating a variable called getTextFile that will not be accessible outside of you initialization.

To explain your error:

scope.getTextFile();

that code is looking for the getTextFile variable on the scope object. Which is undefined. Since it is undefined you cannot called it like a function.

Also you controller needs to accept a $scope variable and you need to set what you want on the $scope not this.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM