【问题标题】:Javascript $.each functionJavascript $.each 函数
【发布时间】:2017-04-27 17:05:03
【问题描述】:

this.CurrentComponent.ExtendedProperties 是从 .Net 返回的 Dictionary<string, string>。当我尝试在客户端读取字典中的值时,在 javascript 中,我得到了该属性的所有对象,我不希望这样。

我有以下代码来填充对象并在 Javascript 中推送到数组。

this.populateExtendedProps = function () {
    if (this.CurrentComponent.ExtendedProperties != null) {
        $.each(this.CurrentComponent.ExtendedProperties, function (key, value) {
            debugger;
            var data = {};
            data.Key = key;
            data.Value = value;
            data.Id = key + "_" + value; //generate
            result.push(data);
        });
    }
};

this.CurrentComponent.ExtendedProperties 对象如下所示: 我想要的只是将键中的 FirstName 和值中的 FirstValue 返回给回调,但我也得到了event: object 等,这不是我想要的。

我怎样才能只返回字典中的实际值,而不是 javascript 对象的所有成员/属性/函数?

更新

这是我从服务器端返回的对象,.Net。从这里可以看出,ExtendedProperties 属性是Dictionary<string, string>

public class ComponentItem 
{
    public Guid ItemId { get; set; }
    public Guid ComponentId { get; set; }
    public Guid? ParentItemId { get; set; }
    public string Name { get; set; }
    public int Rank { get; set; }
    public string Text { get; set; }
    public string Description { get; set; }
    public string URL { get; set; }
    public ComponentRendering OpenIn { get; set; }
    public string Property1 { get; set; }
    public string Property2 { get; set; }
    public bool ActiveOnPreview { get; set; }
    public bool ActiveOnLive { get; set; }
    public Guid RepositoryId { get; set; }
    public string RepositoryPath { get; set; }
    public string CDNUrl { get; set; }
    public bool CanDisableInLive { get; set; }
    public bool CanDelete { get; set; }
    public Dictionary<string, string> ExtendedProperties { get; set; }

}

这个ComponentItem 类被返回到前端以响应Ajax 调用。

这个ExtendedProperty 值是从数据库接收的,作为JSON 字符串,如下:{"FirstName":"FirstValue"}

我使用下面这段代码,将这个 JSON 字符串反序列化为 Dictionary,如下:

private Dictionary<string, string> GetExtendedPropertiesFromJson(string extendedPropertiesJson)
    {
        return JsonConvert.DeserializeObject<Dictionary<string, string>>(extendedPropertiesJson);
    }

【问题讨论】:

  • 你想在服务器端限制细节或者你想在执行循环之前在客户端检查对象的名字
  • 我没有在 .NET 中工作过,所以我不确定服务器端到底发生了什么,但不幸的是他们没有将“真实”数据放入自己的属性中,因为很明显,当它到达 JS 时,它是一个具有属性的常规对象,而不是字典......您当然可以通过在推送之前将它们与键进行比较来将您期望的值列入白名单,但这显然是一种痛苦。
  • 您只想要FirstName 属性,还是也想要uid
  • 正如我在您的图片中看到的,this.CurrentComponent.ExtendedProperties 不是列表/数组。你确定这是一个数组吗?
  • @JericCruz 它是一个对象,但 $.each 也处理它:api.jquery.com/jquery.each

标签: javascript c# jquery asp.net .net


【解决方案1】:

检查value 的类型是快速而肮脏的,但是如果您添加更多属性,这可能会给您带来太多负担。

this.populateExtendedProps = function () {
    if (this.CurrentComponent.ExtendedProperties != null) {
        $.each(this.CurrentComponent.ExtendedProperties, function (key, value) {
            if (typeof (value) === 'string') {
                debugger;
                var data = {};
                data.Key = key;
                data.Value = value;
                data.Id = key + "_" + value; //generate
                result.push(data);
            }
        });
    }
};

【讨论】:

  • 我认为这就是他们所说的“钥匙中的名字”的意思,它是“和钥匙”的拼写错误。如果您对问题的评估是正确的,那么是的,这是不正确的。
  • 是的,我不确定......他们没有说这是否应该是字典项目。我推断它可能不是,因为 FirstName 是大写的驼峰式大小写,而 uid 不是
  • 我已经更新了我的问题。从服务器返回到 Javascript 的对象包含属性 ExtendedProperties。这是一个正在返回的字典。
【解决方案2】:

这并不是真正的最佳解决方案,因为这意味着您必须考虑预期的密钥,并且您不能随时将新密钥添加到服务器端而不更新客户端以允许它们,但取决于有多少可能的键,您可以将您想要允许的键“列入白名单”,然后只推送这些键:

this.populateExtendedProps = function () {

    // List of properties you expect and want
    // to allow into the final list of results.
    var allowedProps = {
      FirstName: true, 
      FooKey: true, 
      BarKey: true
    };

    if (this.CurrentComponent.ExtendedProperties != null) {
        $.each(this.CurrentComponent.ExtendedProperties, function (key, value) {
            debugger;

            if (key in allowedProps) {
              var data = {};
              data.Key = key;
              data.Value = value;
              data.Id = key + "_" + value; //generate
              result.push(data);
            }
        });
    }
};

正如我上面提到的,我对 .NET 不太熟悉,所以我不确定服务器端会发生什么。正如 Naveen 所说,也许有一种方法可以在到达客户端之前修剪除实际 Dictionary 项目之外的所有内容。这显然是一个更好的解决方案……那么您就不必担心这些“内部”属性会混入您的数据中。

【讨论】:

  • 我明白你想提出什么建议,但我认为这不是满足我需求的好解决方案。扩展属性最终将包含数百个键/值对,这意味着每次添加新键时我都需要更新。感谢您的努力,我很感激
  • 是的——就像我说的那样,这并不是一个很好的解决方案,因为它不够灵活。不幸的是,由于您正在处理一个普通对象,因此很难清除内容,除非键或值具有某种一致的模式。很高兴你解决了!
【解决方案3】:

如果没有关于 .NET 应用程序服务器端的更多信息,那么这个问题确实没有最佳解决方案。如果您可以用更多关于如何向前端框架发送响应的详细信息来更新问题,那将是一个很好的开始。如果没有这些信息,我会在我的回答中假设很多东西。

首先,我假设您可以完全控制服务器端代码,并且可以在ApiController/Controller 级别更改代码库。我还将假设您使用的是 .NET MVC 框架。最后,我将假设您正在发回一个 JSON 响应。如果您使用 XML 向前端框架发送响应,则此答案不适用。

在您的 .NET ApiController/Controller(s) 中,您可以排除您不想包含在 JSON 响应中的属性。就像下面的代码一样简单:

[JsonIgnore]
public int Foobar { get; set; }

上述[JsonIgnore](数据注释)将强制.NET JSON响应处理程序在序列化对象时忽略状态(在您的情况下为Dictionary&lt;string, string&gt;)。

更多细节可以在这个answer找到。

【讨论】:

  • @monstertjie_za 根据您更新的问题,由于JsonConvert.DeserializeObject&lt;&gt; 没有添加任何模糊变量,我相信_events 对象不会在服务器级别添加。当您在 .NET 中进行调试时,您真的可以在 ExtendedProperties 中看到 _events 对象吗?你的HttpContext.Response 呢?
  • 不是全部,在.Net中调试时,我的字典只包含从数据库中检索到的有效键:值
  • @monstertjie_za 然后,_events 不应在服务器级别添加。这些值是否可能来自前端的应用程序框架(meteor/vuejs/angular/react/等)?许多应用程序框架会在运行时自动注入他们需要的对象。
【解决方案4】:

为什么我没有只在客户端返回字典项,这对我来说仍然是一个谜,当我找到解决方案时,我会调查并更新这个答案。

现在,我更改了我的 populateExtendedProps 函数,并创建了一个新的服务器端 WebMethod,它返回一个新的 ExtendedProperties 列表。

这是我的服务器端代码:

[WebMethod]
    public Dictionary<string, string> GetExtendedPropertiesForComponentItem(Guid componentItemId)
    {
        return Api.ComponentManager.GetComponentItem(componentItemId).ExtendedProperties;
    }

还有我更新的 Javascript 代码:

this.populateExtendedProps = function () {
    ajax.request(this.baseUrl + "GetExtendedPropertiesForComponentItem", { componentItemId: this.CurrentComponent.ItemId }, this.populateExtendedPropsSuccess);
};

this.populateExtendedPropsSuccess = function (resp) {
    var collection = [];
    if (resp != null) {
        $.each(resp, function (key, value) {
            var data = {};
            debugger;
            data.Key = key;
            data.Value = value;
            data.Id = key + "_" + value; //generate
            collection.push(data);
        });
        scope.onSaveExtendedPropertySuccess(collection);
    }
}

所以populateExtendedProps函数向服务器发送一个ajax post,并在从服务器成功返回时调用populateExtendedPropsSuccess,并传递响应,然后我循环响应。

【讨论】:

    猜你喜欢
    • 2015-05-10
    • 2015-04-08
    • 2014-08-02
    • 2017-12-21
    • 2020-06-17
    • 2010-10-12
    • 2015-01-23
    • 2020-09-05
    • 2015-11-01
    相关资源
    最近更新 更多