如果在angularjs表单中未定义对象,如何返回空字符串

时间:2018-05-21 15:39:25

标签: javascript angularjs

我有一个表单模型,我用它来映射AngularJS中的表单字段。由于我在数据库上更新这些字段,因此我想在用户提交表单后返回字段并返回到该字段。

表单对象:

vm.user = {
        userBag:[
          {
            name: nameService.nameBag[0].organizationName
          },
          {
            name: nameService.nameBag[1].organizationName,
          },
          {
            name: nameService.nameBag[2].organizationName,
          }
        ]
  };

我已经编写了表单对象以返回数据库字段,但是当用户最初没有在字段中提交任何内容时,我遇到了错误bc对象为空。得到错误:

  

“TypeError:无法读取未定义的属性'organizationName'”

nameServie只是一个检索get的get调用。

如果nameServiceundefined,如何设置名称字段只会返回空白?

3 个答案:

答案 0 :(得分:2)

您可以使用三元运算符来实现它:

 vm.user = {
        userBag:[
          {
            name: (nameService && nameService.nameBag && nameService.nameBag[0]) ? nameService.nameBag[0].organizationName : ""
          },
          {
            name: (nameService && nameService.nameBag && nameService.nameBag[1]) ? nameService.nameBag[1].organizationName : ""
          },
          {
            name: (nameService && nameService.nameBag && nameService.nameBag[2]) ? nameService.nameBag[2].organizationName : "",
          }
        ]
    };

答案 1 :(得分:0)

有几种方法可以实现您的目标:

三元运营商

使用三元运算符可以得到类似的结果:

vm.user = {
  userBag:[
    {
      name: nameService ? nameService.nameBag[0].organizationName : ''
    },
    {
      name: nameService ? nameService.nameBag[1].organizationName : ''
    },
    {
      name: nameService ? nameService.nameBag[2].organizationName : ''
    }
  ]
};

或运算符

使用||运算符,您可以评估您要访问的路径是“存在”还是具有值:

{
  name: (nameService && ... && nameService.nameBag[0].organizationName) || ''
}

可选访问功能

然而,为了保持 DRY ,我宁愿使用一个函数进行可选访问,例如:

function optionalAccess(obj, path, def) {
  const propNames = path.replace(/\]|\)/,'').split(/\.|\[|\(/);

  return propNames.reduce((acc, prop) => acc[prop] || def, obj);
}

const obj = {
  items: [{ hello: "Hello" }]
};

console.log(optionalAccess(obj, "items[0].hello", "def")); // prints: Hello
console.log(optionalAccess(obj, "items[0].he", "def")); // prints: def

TC39提案

目前有一个proposal以便能够使用链接,这将允许您执行以下操作:

nameService?.nameBag[0]?.organizationName || ''

如果你想做类似的事情,还有babel插件

https://www.npmjs.com/package/babel-plugin-transform-optional-chaining

答案 2 :(得分:0)

我刚刚遇到了同样的问题。谷歌搜索没有结果,但偶尔我刚刚解决了非常相似的问题,并想到了以下解决方案:

type Pipeline<T> =
  { [K in keyof T]: Pipeline<T[K]> }
  & { VALUE: (defaultValue: T) => T }
export function ppln<T extends {}>(value: T): Pipeline<T> {
  function bound(value: any): boolean {
    return ["string", "number", "boolean", "undefined", "function"]
      .includes(typeof value)
  }
  return new Proxy<T>(
    bound(value) ? {} as T : value, {
    get: (_, field: keyof T) => {
      if (field === "VALUE") {
        return defaultValue => value === undefined ? defaultValue : value
      }
      if (value && value[field]) {
        return ppln(value[field])
      }
      return ppln(undefined)
    }
  }) as unknown as Pipeline<T>
}

那么应该有可能

ppln(obj).prop1[prop2].prop3.VALUE()
ppln(obj).prop1[prop2].prop3.VALUE('default value')

并毫无例外地获取现有值或undefined。 如果请求的值为'default value',第二行将产生undefined