JS严格模式对象字面量重复属性报错 $resource可选参数处理问询
严格模式下禁止对象字面量存在重复键,你在$resource的action配置对象中定义了两个同名的get属性,后者会直接覆盖前者,代码解析阶段就会抛出你看到的报错。靠定义同名action区分可选路径参数的思路,本身不符合AngularJS $resource的设计逻辑。
方案1:使用$resource原生可选路径参数(推荐)
$resource原生支持可选路径参数:调用action时如果没有传入某个路径参数的值,框架会自动把URL中对应的参数段以及前置的多余斜杠移除,完全不需要定义两个同名action。
你只需要保留一个get配置,URL中带上:byteRange参数即可:
(function () { 'use strict'; angular .module('MyApp') .factory('retrieve', retrieveObject); retrieveObject.$inject = ['$resource']; function retrieveObject($resource) { this.resource = $resource('api/tools/test', {}, { 'list': { method: 'GET', url: 'api/tools/test/list/:chain/:path/:dataCenter' }, 'get': { method: 'GET', url: 'api/tools/test/get/:chain/:dataCenter/:path/:byteRange' } }); return this; } })();
调用时传入byteRange字段,值就会自动拼接到路径末尾;不传该字段时,框架会自动生成不带该路径段的请求地址,直接匹配你的需求。
如果使用的是较旧版本的AngularJS,没有自动裁剪空参数段的能力,可以把URL调整为'api/tools/test/get/:chain/:dataCenter/:path:byteRange',同时给action添加参数默认值params: {byteRange: ''},需要传byteRange的时候手动给值加上前置斜杠即可。
方案2:定义不同名action区分场景
如果不想依赖框架的自动裁剪逻辑,可以给两类请求定义不同名的action,从根源上避免重复键问题。调用时根据是否存在ByteRange值,选择对应的action发起请求即可:
function retrieveObject($resource) { this.resource = $resource('api/tools/test', {}, { 'list': { method: 'GET', url: 'api/tools/test/list/:chain/:path/:dataCenter' }, 'get': { method: 'GET', url: 'api/tools/test/get/:chain/:dataCenter/:path' }, 'getWithRange': { method: 'GET', url: 'api/tools/test/get/:chain/:dataCenter/:path/:byteRange' } }); return this; }
这种写法没有隐式逻辑,所有请求路径都明确定义在配置中,后续维护成本最低。
方案3:调用时动态覆盖URL配置
$resource的action调用时支持传入自定义配置覆盖默认值,你也可以只保留不带byteRange的基础get配置,在需要传ByteRange的场景,调用时手动传入带byteRange段的url覆盖默认配置。这种写法会把URL逻辑散落在各个调用处,不利于统一维护,非特殊场景不推荐使用。
内容的提问来源于stack exchange,提问作者Hani Gotc Reinstate Monica

