Javascript (角度错误)继承后不存在函数成员(TypeError:row.dynamicProperties不是函数)

Javascript (角度错误)继承后不存在函数成员(TypeError:row.dynamicProperties不是函数),javascript,angularjs,inheritance,typescript,Javascript,Angularjs,Inheritance,Typescript,我正在运行angular/mvc网站。我把我所有的模型和东西分开。 在某些时候,我觉得需要一个额外的属性,它不是我的模型的一部分。我想到了继承并开始编写代码。 首先我使用了“getter”,看到它是get override simply,我想到了一些类似intellisense的方法更支持的东西,所以人们不会不经思考就简单地重写它 我写的是: /** * Created by Hassan on 4/4/2016. */ abstract class DynamicPropertiesPro

我正在运行angular/mvc网站。我把我所有的模型和东西分开。 在某些时候,我觉得需要一个额外的属性,它不是我的模型的一部分。我想到了继承并开始编写代码。 首先我使用了“getter”,看到它是get override simply,我想到了一些类似intellisense的方法更支持的东西,所以人们不会不经思考就简单地重写它

我写的是:

/**
 * Created by Hassan on 4/4/2016.
 */
abstract class DynamicPropertiesProvider {
    private _dynamicProperties:Object;

    constructor() {
        this._dynamicProperties = {};
    }

    dynamicProperties():Object {
        return this._dynamicProperties;
    }
}
然后我在我的模型中使用它,比如:

/**
 * Created by Hassan on 3/16/2016.
 */

///<reference path="dynamicPropertiesProvider.ts"/>
class AcDocRow extends DynamicPropertiesProvider{
    public FinYear: string;
    public DocNoTemp: number;
    public DocRow: number;
    public HsbCod: string;
    public RowDsc: string;
    public Bedehkar: number;
    public Bestankar: number;
    public Bookmark: boolean;
    public MainDocNo: number;
    public DocDate: string;

    //Getters And Setters
    get CompositeKey():string {
        return this.FinYear + "-" + this.DocNoTemp + "-" + this.DocRow;
    }

    get Date():string {
        return ((this.DocDate) ? this.DocDate.substr(0, 4) + "/" + this.DocDate.substr(4, 2) + "/" + this.DocDate.substr(6, 2) : "");
    }

    constructor(finYear, docNoTemp, docRow, hsbCod, rowDsc, bedehkar, bestankar, bookmark, mainDocNo, docDate){
        super(); //Call Super (Parent) Class Constructor
        this.setup();
        if (finYear != undefined) this.FinYear = finYear;
        if (docNoTemp != undefined) this.DocNoTemp = docNoTemp;
        if (docRow != undefined) this.DocRow = docRow;
        if (hsbCod != undefined) this.HsbCod = hsbCod;
        if (rowDsc != undefined) this.RowDsc= rowDsc;
        if (bedehkar != undefined) this.Bedehkar = bedehkar;
        if (bestankar != undefined) this.Bestankar= bestankar;
        if (bookmark != undefined) this.Bookmark = bookmark;
        if (mainDocNo != undefined) this.MainDocNo= mainDocNo;
        if (docDate != undefined) this.DocDate= docDate;
    }

    private setup():void{
        this.FinYear = "";
        this.DocNoTemp = 0;
        this.DocRow = 0;
        this.HsbCod = "";
        this.RowDsc = "";
        this.Bedehkar = 0;
        this.Bestankar = 0;
        this.Bookmark = false;
        this.MainDocNo = 0;
        this.DocDate = "";
    }

    public copy():AcDocRow{
        return new AcDocRow(this.FinYear, this.DocNoTemp, this.DocRow, this.HsbCod, this.RowDsc, this.Bedehkar, this.Bestankar, this.Bookmark, this.MainDocNo, this.DocDate);
    }

    public resetModel(finYear, docNoTemp, docRow, hsbCod, rowDsc, bedehkar, bestankar, bookmark, mainDocNo, docDate): void{
        this.constructor(finYear, docNoTemp, docRow, hsbCod, rowDsc, bedehkar, bestankar, bookmark, mainDocNo, docDate);
    }
}
对于AcDocRow:

/**
 * Created by Hassan on 3/16/2016.
 */
var __extends = (this && this.__extends) || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
///<reference path="dynamicPropertiesProvider.ts"/>
var AcDocRow = (function (_super) {
    __extends(AcDocRow, _super);
    function AcDocRow(finYear, docNoTemp, docRow, hsbCod, rowDsc, bedehkar, bestankar, bookmark, mainDocNo, docDate) {
        _super.call(this); //Call Super (Parent) Class Constructor
        this.setup();
        if (finYear != undefined)
            this.FinYear = finYear;
        if (docNoTemp != undefined)
            this.DocNoTemp = docNoTemp;
        if (docRow != undefined)
            this.DocRow = docRow;
        if (hsbCod != undefined)
            this.HsbCod = hsbCod;
        if (rowDsc != undefined)
            this.RowDsc = rowDsc;
        if (bedehkar != undefined)
            this.Bedehkar = bedehkar;
        if (bestankar != undefined)
            this.Bestankar = bestankar;
        if (bookmark != undefined)
            this.Bookmark = bookmark;
        if (mainDocNo != undefined)
            this.MainDocNo = mainDocNo;
        if (docDate != undefined)
            this.DocDate = docDate;
    }
    Object.defineProperty(AcDocRow.prototype, "CompositeKey", {
        //Getters And Setters
        get: function () {
            return this.FinYear + "-" + this.DocNoTemp + "-" + this.DocRow;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AcDocRow.prototype, "Date", {
        get: function () {
            return ((this.DocDate) ? this.DocDate.substr(0, 4) + "/" + this.DocDate.substr(4, 2) + "/" + this.DocDate.substr(6, 2) : "");
        },
        enumerable: true,
        configurable: true
    });
    AcDocRow.prototype.setup = function () {
        this.FinYear = "";
        this.DocNoTemp = 0;
        this.DocRow = 0;
        this.HsbCod = "";
        this.RowDsc = "";
        this.Bedehkar = 0;
        this.Bestankar = 0;
        this.Bookmark = false;
        this.MainDocNo = 0;
        this.DocDate = "";
    };
    AcDocRow.prototype.copy = function () {
        return new AcDocRow(this.FinYear, this.DocNoTemp, this.DocRow, this.HsbCod, this.RowDsc, this.Bedehkar, this.Bestankar, this.Bookmark, this.MainDocNo, this.DocDate);
    };
    AcDocRow.prototype.resetModel = function (finYear, docNoTemp, docRow, hsbCod, rowDsc, bedehkar, bestankar, bookmark, mainDocNo, docDate) {
        this.constructor(finYear, docNoTemp, docRow, hsbCod, rowDsc, bedehkar, bestankar, bookmark, mainDocNo, docDate);
    };
    return AcDocRow;
})(DynamicPropertiesProvider);
//# sourceMappingURL=acDocRow.js.map
当我告诉服务返回数据,然后将其绑定到视图时,我的控制器

app.controller("IndexController", [
    "$rootScope", "$scope", "$uibModal", "$timeout", "AcDocRowService", "FinYearService",
    function ($rootScope, $scope, $uibModal, $timeout, AcDocRowService, FinYearService) {

        $scope.View = {
            SarfaslSelectionDialog: {
                ShowDialog: false,
                /**
                 * Output Result Selected Sarfasl
                 */
                SelectedSarfasl: null,
                FinYear: null,
                InitialHsbCod: null
            },
            CodeInfo: {
                LenCod: 0,
                LenK: 0,
                LenM: 0,
                LenT1: 0,
                LenT2: 0,
                LenJ: 0
            },
            OperationMode: null,
            Errors: [],
            AcDocRowList: [],
            AcDocRowFilters:{
                ShowFilters: false,
                Bookmark: null,
                FromDate: "",
                ToDate: "",
                FromDocNoTemp: null,
                ToDocNoTemp: null,
                FromPrice: null,
                ToPrice: null
            },
            AcDocRowSummery: {
                TotalResult: 0,
                CheckedResult: 0,
                UncheckedResult: 0,
                TotalDemand: 0,
                TotalDept: 0,
                CheckedDemand: 0,
                CheckedDept: 0,
                UncheckedDemand: 0,
                UncheckedDept: 0
            },
            SelectedItems: []
        };

        $scope.Events= {
            selectRow: function(row){
                if($scope.View.SelectedItems.contains(row)){
                    $scope.View.SelectedItems.remove(row);
                } else {
                    $scope.View.SelectedItems.push(row)
                }

                //MY OLD CODES WHERE I READ THE 'row' Object

                //if(! row.dynamicProperties()["selected"])
                //    row.dynamicProperties()["selected"]= true;
                //row.dynamicProperties()["selected"] = !row.dynamicProperties()["selected"];
            },
            ...
            //Where i set AcDocRowList, That i use in my View
            searchAcDocRows: function() {
                $scope.Events.openWaitDialog();

                //If Method Called On Start By $Watch, Return
                if($scope.View.SarfaslSelectionDialog.SelectedSarfasl == null){
                    return;
                }

                var sarfaslParams = $scope.View.SarfaslSelectionDialog;

                var filter = "FinYear=" + sarfaslParams.FinYear + "-HsbCod=" + sarfaslParams.SelectedSarfasl.getClearHsbCod();
                AcDocRowService.query({ filter: filter }).$promise.then(
                    function (data) {
                        $scope.Methods.resetTotals();
                        $scope.View.AcDocRowList = data;
                        $scope.Events.closeWaitDialog();
                    }, function (errorResult) {
                        $scope.View.Errors.push(new Alert("Cannot contact web server at this moment. Please try again later.", AlertType.Danger));
                        $scope.Events.closeWaitDialog();
                    }
                );
            }
            ...
        };
        ...

    }
]);
我的看法是:

...
            <tbody>
                <tr data-ng-repeat="row in View.AcDocRowList | filter: Filters.acDocRowFilterFunction"
                    data-ng-class="{'checked-row':row.Bookmark}" data-ng-click="Events.selectRow(row)">
                    <td>
                        <input type="checkbox" ng-model="row.Bookmark" data-ng-click="Events.setBookmark(row)">
                    </td>
                    <td class="number">
                        <!--Restart Total Price-->
                        {{Methods.setTotal($index, row.Bookmark); $index | persianNumberFilter}}
                    </td>
                    <td class="number">{{row.DocNoTemp | persianNumberFilter}}</td>
                    <td>
                        <!--row.Date is a 'getter' -->
                        {{row.Date | persianNumberFilter}}
                    </td>
                    <td>{{row.RowDsc | persianNumberFilter}}</td>
                    <td class="number">{{row.Bedehkar!=0?row.Bedehkar:"" | priceFilter | persianNumberFilter}}</td>
                    <td class="number">{{row.Bestankar!=0?row.Bestankar:"" | priceFilter | persianNumberFilter}}</td>
                    <td>
                        {{Methods.getTashkhis()}}
                    </td>
                    <td class="number">
                        {{Methods.getRemains()!=0?Methods.getRemains():"" | priceFilter | persianNumberFilter}}
                    </td>
                </tr>
            </tbody>
...
。。。
{Methods.setTotal($index,row.Bookmark);$index | persianNumberFilter}
{{row.DocNoTemp | persianNumberFilter}}
{{row.Date}persianNumberFilter}
{{row.RowDsc | persianNumberFilter}}
{{row.Bedehkar!=0?row.Bedehkar:| priceFilter | persianNumberFilter}
{{row.Bestankar!=0?row.Bestankar:| priceFilter | persianNumberFilter}
{{Methods.getTashkhis()}}
{{Methods.getresistes()!=0?Methods.getresistes():“| priceFilter | persianNumberFilter}”
...

解决了的 AngularJs ngResource不直接解析transformResponse操作。它将其传递给angular core中的$http来处理它。一旦结果出来。它再次折叠资源类对象内的数据。这就是资源构造函数执行名为方法的浅层复制的时候。正如它的名字所说,更深层次的很多东西都会丢失,对象类型也会改变

我通过更新资源解决了这个问题,并提供了新的操作“transformResult”,我使用它而不是transformResponse。 在ngResource将结果传递给用户之前,它会在最后执行它的作业

我也提出了拉的要求,我不这么认为,但我希望他们能接受。
我怀疑您有模块订购问题。我建议不要使用
outFile
并研究如何使用模块模式,例如commonjs:

我修改了ngResource,并提出了一个pull请求,该请求提供了转换服务最新结果的功能。

抽象类仅在typescript版本1.6之后可用。是否使用1.6或更高版本编译?编译器版本:1.6.2(捆绑)编译正常。如果您将代码粘贴到这里,您将得到相同的编译,并且可以正常工作。我猜你的问题是“行”不是你正在等待的对象类型。我修改了我的帖子,并添加了我的角度绑定信息。控制器和服务中的cod不是typescript。那么,您如何确定通过了正确的类型?有两种选择:行不是想要的类型,或者正如basarat所说的,文件没有按照正确的顺序编译,所以你的意思是我的AcDocRow需要重新编译?我试了一下,但没有成功。或者你指的是其他东西,我指的是顺序,如果编译的JavaScript可能是错误的。例如,
console.log(foo)之类的东西;var foo=123
而不是
var foo=123;console.log(foo)可能正在发生。我尝试过(首先我编译了抽象,然后是继承的类)。。。不工作。。。在js文件中。。。它之前给出了错误,所以我将父文件放在绑定队列的开头
app.controller("IndexController", [
    "$rootScope", "$scope", "$uibModal", "$timeout", "AcDocRowService", "FinYearService",
    function ($rootScope, $scope, $uibModal, $timeout, AcDocRowService, FinYearService) {

        $scope.View = {
            SarfaslSelectionDialog: {
                ShowDialog: false,
                /**
                 * Output Result Selected Sarfasl
                 */
                SelectedSarfasl: null,
                FinYear: null,
                InitialHsbCod: null
            },
            CodeInfo: {
                LenCod: 0,
                LenK: 0,
                LenM: 0,
                LenT1: 0,
                LenT2: 0,
                LenJ: 0
            },
            OperationMode: null,
            Errors: [],
            AcDocRowList: [],
            AcDocRowFilters:{
                ShowFilters: false,
                Bookmark: null,
                FromDate: "",
                ToDate: "",
                FromDocNoTemp: null,
                ToDocNoTemp: null,
                FromPrice: null,
                ToPrice: null
            },
            AcDocRowSummery: {
                TotalResult: 0,
                CheckedResult: 0,
                UncheckedResult: 0,
                TotalDemand: 0,
                TotalDept: 0,
                CheckedDemand: 0,
                CheckedDept: 0,
                UncheckedDemand: 0,
                UncheckedDept: 0
            },
            SelectedItems: []
        };

        $scope.Events= {
            selectRow: function(row){
                if($scope.View.SelectedItems.contains(row)){
                    $scope.View.SelectedItems.remove(row);
                } else {
                    $scope.View.SelectedItems.push(row)
                }

                //MY OLD CODES WHERE I READ THE 'row' Object

                //if(! row.dynamicProperties()["selected"])
                //    row.dynamicProperties()["selected"]= true;
                //row.dynamicProperties()["selected"] = !row.dynamicProperties()["selected"];
            },
            ...
            //Where i set AcDocRowList, That i use in my View
            searchAcDocRows: function() {
                $scope.Events.openWaitDialog();

                //If Method Called On Start By $Watch, Return
                if($scope.View.SarfaslSelectionDialog.SelectedSarfasl == null){
                    return;
                }

                var sarfaslParams = $scope.View.SarfaslSelectionDialog;

                var filter = "FinYear=" + sarfaslParams.FinYear + "-HsbCod=" + sarfaslParams.SelectedSarfasl.getClearHsbCod();
                AcDocRowService.query({ filter: filter }).$promise.then(
                    function (data) {
                        $scope.Methods.resetTotals();
                        $scope.View.AcDocRowList = data;
                        $scope.Events.closeWaitDialog();
                    }, function (errorResult) {
                        $scope.View.Errors.push(new Alert("Cannot contact web server at this moment. Please try again later.", AlertType.Danger));
                        $scope.Events.closeWaitDialog();
                    }
                );
            }
            ...
        };
        ...

    }
]);
...
            <tbody>
                <tr data-ng-repeat="row in View.AcDocRowList | filter: Filters.acDocRowFilterFunction"
                    data-ng-class="{'checked-row':row.Bookmark}" data-ng-click="Events.selectRow(row)">
                    <td>
                        <input type="checkbox" ng-model="row.Bookmark" data-ng-click="Events.setBookmark(row)">
                    </td>
                    <td class="number">
                        <!--Restart Total Price-->
                        {{Methods.setTotal($index, row.Bookmark); $index | persianNumberFilter}}
                    </td>
                    <td class="number">{{row.DocNoTemp | persianNumberFilter}}</td>
                    <td>
                        <!--row.Date is a 'getter' -->
                        {{row.Date | persianNumberFilter}}
                    </td>
                    <td>{{row.RowDsc | persianNumberFilter}}</td>
                    <td class="number">{{row.Bedehkar!=0?row.Bedehkar:"" | priceFilter | persianNumberFilter}}</td>
                    <td class="number">{{row.Bestankar!=0?row.Bestankar:"" | priceFilter | persianNumberFilter}}</td>
                    <td>
                        {{Methods.getTashkhis()}}
                    </td>
                    <td class="number">
                        {{Methods.getRemains()!=0?Methods.getRemains():"" | priceFilter | persianNumberFilter}}
                    </td>
                </tr>
            </tbody>
...