获取要在ng-options中显示的数据,但设置动态默认值

时间:2017-07-25 15:23:20

标签: javascript angularjs json

用户对象可用于填充表单的视图。显示信息的元素之一是下拉列表。提出了两项​​请求。一个用于user information,另一个用于timezones列表。两者都通过ui-router状态解决,如下所示:

.state('app.userprofile', {
        url: '/userprofile',
        component: 'user',
        resolve: {
            user: ['userService', function(userService) {
                return userService.fetchUser();
            }],
            timezones: ['timezoneService', function(timezoneService){
                return timezoneService.fetchUsaTimeZones();
            }]
        }
    })
}]);

select元素无法填充用户时区后,我已经在线阅读article,但是select元素仍然无法显示信息。

问题

如何使用来自用户object的数据填充默认选择选项,但填充第二个响应中的选项。

<label for="timezones">Time Zone</label>
    <div>
        <select name="timezones"
            ng-init="userTimezone = $ctrl.user.business.timezone"
            ng-change="userTimezone = userTimezone.abbr"
            ng-model="userTimezone" 
            ng-options="item as item.abbr for item in $ctrl.timezones track by item.abbr" class="form-control">
            <option value="">{{userTimezone}}</option>
        </select>
        <p>{{userTimezone}}</p>
    </div>


//SECOND REQUEST FOR TIMEZONES
app.factory('timezoneService', ['$http', '$q', function($http, $q){

    var factory = {};

    factory.fetchUsaTimeZones = function() {

        var deferred = $q.defer();

        $http.get('../../p3sweb/assets/json/ustimezones.json')
        .then(
            function(response){
                console.log(response.data.ustimezones)
                deferred.resolve(response.data.ustimezones)
            },
            function(errResponse){
                deferred.resolve(errResponse)
            }
        );

        return deferred.promise;
    }

    return factory;

}])
{
  "ustimezones": [
  {
    "value": "Hawaiian Standard Time",
    "abbr": "HST",
    "offset": -10,
    "isdst": false,
    "text": "(UTC-10:00) Hawaii",
    "utc": [
      "Etc/GMT+10",
      "Pacific/Honolulu",
      "Pacific/Johnston",
      "Pacific/Rarotonga",
      "Pacific/Tahiti"
    ]
  },
  {
    "value": "Alaskan Standard Time",
    "abbr": "AKDT",
    "offset": -8,
    "isdst": true,
    "text": "(UTC-09:00) Alaska",
    "utc": [
      "America/Anchorage",
      "America/Juneau",
      "America/Nome",
      "America/Sitka",
      "America/Yakutat"
    ]
  }
  ]
}

更新

我将ng-model的值设为$ctrl.user.business.timezone时抛出了错误,因此我通过userTimezone指令将其存储在变量ng-init中。更新了代码

更新2

我有半工作。它会更新所有字段,但它会抛出一个不一致的405错误。不会撒谎,我在其中一个“这个工作到底是怎么回事”的情况。

<select name="timezones"
    ng-init="userTimezone._abbr = {abbr: $ctrl.user.business.timezone}"
    ng-change="$ctrl.user.business.timezone = userTimezone._abbr"
    ng-model="userTimezone._abbr" 
    ng-options="zone.abbr as zone.text for zone in $ctrl.timezones track by zone.abbr" class="form-control">
<option value="">{{userTimezone._abbr}}</option>
</select>
<p>{{userTimezone._abbr}}</p>

1 个答案:

答案 0 :(得分:2)

您有复杂的对象作为选项。当检查默认值(通过ng-model属性设置)时,Angular会进行相等比较,因此对于对象,它会比较对象引用(通过生成的$$hashkey属性)。因为您有两个不同的对象引用,一次来自时区列表,一次来自用户,它们的哈希键是不同的。因此,它们被视为“不相等”,因此不会设置默认值。

如果将ng-options属性扩展为使用track by,则可以选择一个唯一的原始属性,其中相等比较更有意义(例如缩写)。然后,Angular将使用此属性进行相等/唯一性比较,而不是使用hashkey。

所以你有类似

的东西
<select name="timezones" ng-model="$ctrl.user.business.timezone" ng-options="item as item.abbr for item in $ctrl.timezones track by item.abbr"></select>