ng-options与angularjs中的对象数组

时间:2015-05-14 15:51:27

标签: arrays angularjs drop-down-menu javascript-objects ng-options

我看到了很多关于我在网上看到的变化的引用,但似乎无法找到实际的解决方案。我试图使用AngularJs获取现有数据集来填充选择列表。我可以让它工作,但结果有问题。

我的数据集是一个数组,之前为不同的指令填充,该指令由一组javascript对象实例组成。 (我创建了对象来表示Doctrine实体并从json数据中填充它们)

var ListtypeModel = function(data) {
    var dataIsObj = (typeof(data) == "object");
    this.ListtypeId   = (dataIsObj && (data.ListtypeId > 0))                   ? data.ListtypeId   : null;
    this.ListtypeName = (dataIsObj && (typeof(data.ListtypeName) == "string")) ? data.ListtypeName : null;

    // alias functions
    this.getId   = function() { return this.ListtypeId; }
    this.getName = function() { return this.ListtypeName; }
};

function groupTypes(inData) {
    var grouped = [];
    for(var type in inData) {
        var gType = new ListtypeModel(inData[type]);
        grouped.push(gType);
    }
    return grouped;
}

在主控制器中绘制树状菜单的上半部分时检索信息:

// run at startup
$http.get("<?= $this->basePath(); ?>/json/listtypes")
.success(
    function (response) {
        $scope.types = groupTypes(response.types); // groupLists(response);
    }
);

由于我想在选择菜单中重复使用它,我会传递&#39;类型&#39;通过范围向下变换树,直到它到达弹出编辑指令。

<script type="text/ng-template" id="listedit.html">
    <div class="panel panel-default" style="width:300px;" ng-show="showlistedit">
        <div class="panel-heading" ng-show="(currentlist.ListId > 0)">
            Id: {{ currentlist.ListId  }}
            <input type="hidden" ng-model="listform.listid " ngDisabled="!(currentlist.ListId  > 0)" />
        </div>
        <div class="panel-body">
            <label for="ListName">Name</label>
            <input name="ListName"  type="text" ng-model="listform.name" />
            <br />
            <label for="ListtypeId">Type {{types}}</label>
            <select ng-model="listform.typeid">
                <option ng-selected="listtype.getId() == listform.typeid" ng-repeat="listtype in types" value="{{listtype.getId()}}">{{listtype.getName()}}</option>
            </select>
        </div>
        <span ng-click="saveList()">[save]</span>
    </div>
</script>

    .directive(
        'listedit',
        function($http) {
            return {
                restrict: 'EA',
                replace: true,
                scope: {
                    currenttype: '=',
                    currentlist: '=',
                    showlistedit: '=',
                    types: '='
                },
                templateUrl: 'listedit.html',
                link: function (scope, element, attrs) {
                    scope.listform = {
                        listid : scope.currentlist.ListId,
                        name   : scope.currentlist.ListName,
                        typeid : scope.currentlist.ListtypeId
                    };
                    scope.saveList = function () {
                        alert('in saveList');
                        var postData = $.param({
                            ListId       : scope.listform.listid,
                            ListName     : scope.listform.name,
                            ListtypeId   : scope.listform.typeid
                        });
                        $http({
                            url: '<?= $this->basePath(); ?>/json/lists/save',
                            method: 'POST',
                            data: postData,
                            headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
                        })
                            .success(function (data, status, headers, config) {
                                alert('saveList success');
                            })
                            .error(function (data, status, headers, config) {
                                alert('saveList failure');
                            });
                    }
                }
            }
        })

我还尝试删除标记并在select标记中使用ng-options="listtype.ListtypeId as listtype.ListtypeName for listtype in types"

每当我将选项标签与ng-repeat一起使用时,我会在选择列表的顶部看到两个空白:

<option value="? number:1 ?"></option>
<option value="? undefined:undefined ?"></option>

每当我使用ng-options时,列表会显示两次,其中包含数组中项目的重复项。我在ng-options的重复项上看到至少有一篇帖子说运行$ compile会导致它编译两次,但是我没有编译该指令。

我只需要知道如何使用angularjs来构建没有重复且没有空格的选择列表。

以下是chrome中的console.log()输出中显示的变量:

types as seen in javascript console:
[ListtypeModel, ListtypeModel, ListtypeModel]
  0: ListtypeModel
    $$hashKey: "object:3"
    ListtypeId: 1
    ListtypeName: "Materials"
    getId: function () { return this.ListtypeId; }
    getName: function () { return this.ListtypeName; }
    __proto__: ListtypeModel
  1: ListtypeModel
    $$hashKey: "object:4"
    ListtypeId: 2
    ListtypeName: "Material Collection List"
    getId: function () { return this.ListtypeId; }
    getName: function () { return this.ListtypeName; }
    __proto__: ListtypeModel
  2: ListtypeModel
    $$hashKey: "object:5"
    ListtypeId: 3
    ListtypeName: "Material Collection"
    getId: function () { return this.ListtypeId; }
    getName: function () { return this.ListtypeName; }
    __proto__: ListtypeModel
  length: 3
  __proto__: Array[0]


listform as seen in console.log
  Object {listid: 1, name: "All Materials", typeid: 1}

1 个答案:

答案 0 :(得分:0)

经过相当的修补,我开始怀疑它可能与指令元素嵌套在树结构中的方式有​​关。我正在玩的其中一件事是直接访问templateCache来提取内容,只有当一棵树在其当前分支下有内容时才附加内容。

即。 listType分支到与该类型匹配的列表。然后List有一个listItem数组。 listItems可以有listItemoptions。如果由于任何原因某个类型与当前定义的列表没有匹配,则列表中还没有任何项目或项目没有与之关联的选项,我没有看到任何理由甚至包括允许你进一步扩展这些分支的代码,所以我在链接中使用了条件,然后是编译调用。

e.g。

if (angular.isArray(scope.currentitem.Itemoptions)) {
    element.append($templateCache.get('itemfunc.html'));
    $compile(element.contents())(scope)
}

我不确定是否是嵌套在树下的编译或我从模板缓存中删除项目的事实,但是当我直接将内容包含在图层中时,奇怪的行为就消失了程。

所以我想我只是用ng-show条件隐藏它们。