角度控制器(和范围)继承如何工作

时间:2015-07-26 19:08:15

标签: angularjs

我试图找出控制器继承的工作原理。我有三个控制器:

package com.example.praduman.humlog;

import java.io.Serializable;

/**
 * Created by Praduman on 23/07/2015.
 */
public class HumLogController implements Serializable{
    private transient HumLogModel humLogModel;
    private transient String username;
    private transient String password;
    public transient String userType;

    public HumLogController() {
        this.humLogModel = new HumLogModel();
    }
    public void createNewUser(){
        humLogModel.createNewUser("TestUser4", "1234");
    }
}

The log cat is ...

07-26 15:07:23.785    8885-8885/? D/dalvikvm﹕ Late-enabling CheckJNI
07-26 15:07:23.805    8885-8891/? D/dalvikvm﹕ Debugger has detached; object registry had 1 entries
07-26 15:07:23.905    8885-8888/? D/dalvikvm﹕ GC_CONCURRENT freed 201K, 3% free 8981K/9212K, paused 2ms+0ms, total 7ms
07-26 15:07:23.909    8885-8900/? I/dalvikvm﹕ Could not find method android.database.Cursor.getNotificationUri, referenced from method com.parse.ParseSQLiteCursor.getNotificationUri
07-26 15:07:23.909    8885-8900/? W/dalvikvm﹕ VFY: unable to resolve interface method 489: Landroid/database/Cursor;.getNotificationUri ()Landroid/net/Uri;
07-26 15:07:23.909    8885-8900/? D/dalvikvm﹕ VFY: replacing opcode 0x72 at 0x0002
07-26 15:07:23.913    8885-8885/? I/dalvikvm﹕ Could not find method android.content.res.TypedArray.getChangingConfigurations, referenced from method android.support.v7.internal.widget.TintTypedArray.getChangingConfigurations
07-26 15:07:23.913    8885-8885/? W/dalvikvm﹕ VFY: unable to resolve virtual method 441: Landroid/content/res/TypedArray;.getChangingConfigurations ()I
07-26 15:07:23.913    8885-8885/? D/dalvikvm﹕ VFY: replacing opcode 0x6e at 0x0002
07-26 15:07:23.921    8885-8885/? I/dalvikvm﹕ Could not find method android.content.res.TypedArray.getType, referenced from method android.support.v7.internal.widget.TintTypedArray.getType
07-26 15:07:23.921    8885-8885/? W/dalvikvm﹕ VFY: unable to resolve virtual method 463: Landroid/content/res/TypedArray;.getType (I)I
07-26 15:07:23.921    8885-8885/? D/dalvikvm﹕ VFY: replacing opcode 0x6e at 0x0002
07-26 15:07:23.925    8885-8885/? I/dalvikvm﹕ Could not find method android.content.res.Resources.getDrawable, referenced from method android.support.v7.internal.widget.ResourcesWrapper.getDrawable
07-26 15:07:23.925    8885-8885/? W/dalvikvm﹕ VFY: unable to resolve virtual method 404: Landroid/content/res/Resources;.getDrawable (ILandroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;
07-26 15:07:23.929    8885-8885/? D/dalvikvm﹕ VFY: replacing opcode 0x6e at 0x0002
07-26 15:07:23.929    8885-8885/? I/dalvikvm﹕ Could not find method android.content.res.Resources.getDrawableForDensity, referenced from method android.support.v7.internal.widget.ResourcesWrapper.getDrawableForDensity
07-26 15:07:23.929    8885-8885/? W/dalvikvm﹕ VFY: unable to resolve virtual method 406: Landroid/content/res/Resources;.getDrawableForDensity (IILandroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;
07-26 15:07:23.929    8885-8885/? D/dalvikvm﹕ VFY: replacing opcode 0x6e at 0x0002
07-26 15:07:23.997    8885-8888/? D/dalvikvm﹕ GC_CONCURRENT freed 268K, 4% free 9101K/9396K, paused 1ms+2ms, total 8ms
07-26 15:07:24.057    8885-8885/? D/AndroidRuntime﹕ Shutting down VM
07-26 15:07:24.057    8885-8885/? W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0xa4c3e648)
07-26 15:07:24.057    8885-8885/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.praduman.humlog/com.example.praduman.humlog.LogInActivity}: java.lang.NullPointerException
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
            at android.app.ActivityThread.access$600(ActivityThread.java:141)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:5103)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:525)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.NullPointerException
            at com.example.praduman.humlog.HumLogController.createNewUser(HumLogController.java:18)
            at com.example.praduman.humlog.LogInActivity.onCreate(LogInActivity.java:23)
            at android.app.Activity.performCreate(Activity.java:5133)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
            at android.app.ActivityThread.access$600(ActivityThread.java:141)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:5103)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:525)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
            at dalvik.system.NativeStart.main(Native Method)

和我的观点

var myApp = angular.module('app', []);

myApp.controller('MainController', ['$scope', function($scope) {
    $scope.name = 'main';
    $scope.getName = function() {
        return $scope.name;
    };
}]);
myApp.controller('Child1', ['$scope', function($scope) {
    $scope.name = 'child1';
}]);
myApp.controller('Child2', ['$scope', function($scope) {
    $scope.name = 'child2';
}]);

但他们都显示“主要”。我该如何解决这个问题?

这是一个小提琴http://jsfiddle.net/g3xzh4ov/3/

3 个答案:

答案 0 :(得分:2)

Here's an example如何在Angular中扩展控制器。

myApp.service('baseCtrl', function () {
  this.name = 'base';
  this.getName = function() {
    return this.name;
  };
});

myApp.controller('MainController', ['baseCtrl', function (baseCtrl) {
  angular.extend(this, baseCtrl);
  this.name = 'main';
}]);
myApp.controller('Child1', ['baseCtrl', function (baseCtrl) {
  angular.extend(this, baseCtrl);
  this.name = 'child1';
}]);
myApp.controller('Child2', ['baseCtrl', function (baseCtrl) {
  angular.extend(this, baseCtrl);
  this.name = 'child2';
}]);

它必须使用controllerAs,将$scope替换为this,这对于此类情况特别有用。

注意service而不是其他Angular服务类型的使用,它使用了new,因此可以将this...语句从控制器带到单独的服务。

有几种方法可以进行控制器继承。这是another approach

关于原始代码,Angular中没有'controller iheritance'。并且$scope原型继承假设

$scope.getName = function() {
    return $scope.name;
};

从定义它的上下文返回$scope.name,在你的情况下它是MainController函数。

答案 1 :(得分:1)

您面临的问题实际上是基于核心Javascript功能。

你知道,你所面临的困惑源于范围界定和原型继承的混合。复制属性,但范围保持不变,阻止您访问您希望能够访问的变量。要更好地理解这一点,也许可以代替$scope,我们可以看一个更简单的变量:

myApp.controller('MainController', ['$scope', function($scope) {
    var a = 1;
    $scope.getName = function() {
        console.log(a); // -> 1
        console.log(b); // Error! `Uncaught ReferenceError: b is not defined`
    };
}]);
myApp.controller('Child1', ['$scope', function($scope) {
    var b = 2;
}]);

显然,MainController并不知道Child1定义了一个名为b的变量,因此它出错了。该变量严格超出词汇范围。

同样,如果我们将b重命名为a,则无法将MainController中的值转换为2.这可以准确地说明了您的具体情况:你有三个叫$scope的东西,只有一个在词法范围内。

修复它的两个选项:

1)使用this

$scope.getName = function() {
    return this.name;
};

this解决方案的工作原理是因为Javascript如何确定"这个"基于背景。基本上,由于它附加到给定的$scope对象,因此该对象是一个很好的候选对象。但是Mozilla可以比我更好地解释这一点,所以在这里查看关于这个主题的页面:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this

2)否则,您只需传递$scope

即可
$scope.getName = function(item) {
    return item.name;
};

答案 2 :(得分:0)

如果要覆盖子范围中的name属性,请将原始名称属性转换为object。

$scope.user = {};
$scope.user.name='main';
    $scope.getName = function() {
        return $scope.user.name;
    };

您应该阅读https://github.com/angular/angular.js/wiki/Understanding-Scopes了解详细信息。