Tôi đang trong quá trình tùy chỉnh thông báo xác thực. Nó hoạt động tốt bằng cách sử dụng thuộc tính messageTemplates. Tuy nhiên, nó sử dụng% displayName% để hiển thị tên của thuộc tính và tôi không thể tìm hiểu cách ghi đè giá trị này? Có cách nào để làm điều đó ?breezejs: ghi đè tên hiển thị
Trả lời
Đây không phải là tài liệu YET tốt nhưng bạn chỉ có thể đặt thuộc tính 'displayName' trên bất kỳ dataProperty nào và điều này sẽ ghi đè tên hiển thị được tạo tự động và sẽ được sử dụng cho tất cả các thông báo xác thực cho thuộc tính này. Vì vậy,
var custType = myEntityManager.metadataStore.getEntityType("Customer");
var dp = custType.getProperty("companyName");
dp.displayName = "My custom display name";
Ngoài ra, xin vui lòng xem "Tùy chỉnh các mẫu thông báo" ở dưới cùng của trang này: Breeze Validation
Tôi đã muốn làm điều này cũng nhưng tôi muốn sử dụng [DisplayName] thuộc tính từ EF của tôi mô hình. Tôi không thể tìm thấy bất cứ ai có một ví dụ về làm điều này vì vậy sau khi tôi tìm thấy một cách tôi nghĩ rằng tôi sẽ chia sẻ.
Trước tiên, tôi mở rộng các siêu dữ liệu trở về từ BreezeController tôi:
[HttpGet]
public string Metadata()
{
// Extend metadata with extra attributes
JObject metadata = JObject.Parse(contextProvider.Metadata());
string nameSpace = metadata["schema"]["namespace"].ToString();
foreach (var entityType in metadata["schema"]["entityType"])
{
string typeName = entityType["name"].ToString();
Type t = Type.GetType(nameSpace + "." + typeName);
foreach (var prop in t.GetProperties())
{
foreach (var attr in prop.CustomAttributes)
{
string name = attr.GetType().Name;
foreach (var p in entityType["property"])
{
if (prop.Name == p["name"].ToString()) {
if (attr.AttributeType.Name == "DisplayNameAttribute") {
DisplayNameAttribute a = (DisplayNameAttribute)Attribute.GetCustomAttribute(prop, typeof(DisplayNameAttribute));
p["displayName"] = a.DisplayName;
break;
}
}
}
}
}
}
return metadata.ToString();
}
Sau đó, tôi đã thêm một chút javascript sau khi tải siêu dữ liệu để chọc tên hiển thị từ các siêu dữ liệu gia tăng nơi Breeze muốn tìm thấy chúng.
manager.fetchMetadata().then(function (md) {
angular.forEach(md.schema.entityType, function (et) {
var etype = manager.metadataStore.getEntityType(et.name);
angular.forEach(et.property, function (p) {
var prop = etype.getProperty(p.name);
prop.displayName = p.displayName;
});
});
console.log("starting app");
angular.bootstrap($("#app"), ["app"]);
});
Tôi đang sử dụng góc cạnh nên nếu bạn không phải là bạn có thể bỏ qua nội dung góc cạnh và có thể có ý tưởng. Điều này dường như làm việc khá độc đáo. Nó sẽ được khá dễ dàng để mở rộng này đến các thuộc tính mô hình khác cũng như các thuộc tính xác nhận RegularExpression. Có lẽ tôi sẽ làm việc tiếp theo.
FYI, một số mã này không được tối ưu hóa và có thể có thể được tái cấu trúc, prettied lên một chút nhưng tôi chỉ có nó làm việc và nghĩ rằng tôi sẽ chia sẻ. Nếu bất cứ ai có bất kỳ lời đề nghị của một cách tốt hơn cho tôi biết. Hy vọng rằng Breeze sẽ cho phép mở rộng siêu dữ liệu theo cách được hỗ trợ nhiều hơn trong tương lai. Điều này có vẻ như một chút của một hack.
Nhìn vào http://www.breezejs.com/sites/all/apidocs/files/a40_entityMetadata.js.html#l1452,
này có thể được cải thiện bằng cách đổi tên là "tên" giá trị hiện có để nameOnServer (để đáp ứng các cuộc gọi getDataProperty) và chèn giá trị DisplayNameAttribute là "tên"?
Tiếp theo yêu cầu jpcoder cho các đề xuất, ở đây đi phần máy chủ được cải thiện đôi chút tôi:
JObject metadata = JObject.Parse(contextProvider.Metadata());
string nameSpace = metadata["schema"]["namespace"].ToString();
foreach (var entityType in metadata["schema"]["entityType"])
{
string typeName = entityType["name"].ToString();
Type t = Type.GetType(nameSpace + "." + typeName);
IEnumerable<JToken> metaProps = null;
if (entityType["property"].Type == JTokenType.Object)
metaProps = new[] { entityType["property"] };
else
metaProps = entityType["property"].AsEnumerable();
var props = from p in metaProps
let pname = p["name"].ToString()
let prop = t.GetProperties().SingleOrDefault(prop => prop.Name == pname)
where prop != null
from attr in prop.CustomAttributes
where attr.AttributeType.Name == "DisplayNameAttribute"
select new
{
Prop = p,
DisplayName = ((DisplayNameAttribute)Attribute.GetCustomAttribute(prop, typeof(DisplayNameAttribute))).DisplayName
};
foreach (var p in props)
p.Prop["displayName"] = p.DisplayName;
}
Một sự thay đổi cần thiết để mã máy chủ là, nếu các lớp mô hình của bạn là trong hội đồng khác nhau, bạn không thể sử dụng
Type t = Type.GetType(nameSpace + "." + typeName);
Bạn cần không gian tên cho mỗi loại (trong siêu dữ liệu) và (tôi nghĩ) để sử dụng BuildManager để định vị các loại thích hợp trong các hội đồng khác nhau. Ánh xạ từ cSpaceOSpaceMapping có thể đạt được thanh lịch hơn, nhưng tôi không có thời gian để nghiên cứu các tùy chọn định dạng json khác nhau.
JObject metadata = JObject.Parse(UnitOfWork.Metadata());
string EFNameSpace = metadata["schema"]["namespace"].ToString();
string typeNameSpaces = metadata["schema"]["cSpaceOSpaceMapping"].ToString();
typeNameSpaces = "{" + typeNameSpaces.Replace("],[", "]|[").Replace("[", "").Replace("]", "").Replace(",", ":").Replace("|", ",") + "}";
JObject jTypeNameSpaces = JObject.Parse(typeNameSpaces);
foreach (var entityType in metadata["schema"]["entityType"])
{
string typeName = entityType["name"].ToString();
string defaultTypeNameSpace = EFNameSpace + "." + typeName;
string entityTypeNameSpace = jTypeNameSpaces[defaultTypeNameSpace].ToString();
Type t = BuildManager.GetType(entityTypeNameSpace, false);
IEnumerable<JToken> metaProps = null;
if (entityType["property"].Type == JTokenType.Object)
metaProps = new[] { entityType["property"] };
else
metaProps = entityType["property"].AsEnumerable();
var props = from p in metaProps
let pname = p["name"].ToString()
let prop = t.GetProperties().SingleOrDefault(prop => prop.Name == pname)
where prop != null
from attr in prop.CustomAttributes
where attr.AttributeType.Name == "DisplayNameAttribute"
select new
{
Prop = p,
DisplayName = ((DisplayNameAttribute)Attribute.GetCustomAttribute(prop, typeof(DisplayNameAttribute))).DisplayName
};
foreach (var p in props)
{
p.Prop["displayName"] = p.DisplayName;
}
}
JObject metadata = JObject.Parse(this._context.Metadata());
string EFNameSpace = metadata["schema"]["namespace"].ToString();
string typeNameSpaces = metadata["schema"]["cSpaceOSpaceMapping"].ToString();
typeNameSpaces = "{" + typeNameSpaces.Replace("],[", "]|[").Replace("[", "").Replace("]", "").Replace(",", ":").Replace("|", ",") + "}";
JObject jTypeNameSpaces = JObject.Parse(typeNameSpaces);
foreach (var entityType in metadata["schema"]["entityType"])
{
string typeName = entityType["name"].ToString();
string defaultTypeNameSpace = EFNameSpace + "." + typeName;
string entityTypeNameSpace = jTypeNameSpaces[defaultTypeNameSpace].ToString();
Type t = BuildManager.GetType(entityTypeNameSpace, false);
IEnumerable<JToken> metaProps = null;
if (entityType["property"].Type == JTokenType.Object)
metaProps = new[] { entityType["property"] };
else
metaProps = entityType["property"].AsEnumerable();
var props = from p in metaProps
let pname = p["name"].ToString()
let prop = t.GetProperties().SingleOrDefault(prop => prop.Name == pname)
where prop != null
from attr in prop.CustomAttributes
where attr.AttributeType.Name == "DisplayAttribute"
select new
{
Prop = p,
DisplayName = ((DisplayAttribute)Attribute.GetCustomAttribute(prop, typeof(DisplayAttribute))).Name
};
foreach (var p in props)
{
p.Prop["displayName"] = p.DisplayName;
}
}
return metadata.ToString();
Trong khi mã này có thể trả lời câu hỏi, tốt hơn nên bao gồm một số _context_, giải thích _how_ nó hoạt động và _when_ để sử dụng nó. Câu trả lời chỉ có mã không hữu ích trong thời gian dài. –
Cải thiện câu trả lời jpcoder của ...
Đối với tôi hầu hết những thay đổi DisplayName của tôi đã thay thế "PascalCaseFieldName" hoặc "camelCaseFieldName" với "Upper Trường hợp Tên trường".Vì vậy, thay vì đặt mọi thuộc tính DisplayName trên máy chủ, tôi đã áp dụng một hàm mặc định để đặt displayName.
Kết quả cuối cùng là ít hơn chú thích EF cần thiết. My TypeScript là:
manager.metadataStore.getEntityTypes().forEach(function (storeEntityType) {
if (!(storeEntityType instanceof breeze.EntityType)) {
throw new Error("loadExtendedMetadata found '" + storeEntityType
+ "' StructuralType that is not an EntityType (e.g. a ComplexType)");
}
var extEntityType = extendedMetadata.entitiesExtended.find((extendedEntityType) => {
return extendedEntityType.shortName + ":#" + extendedEntityType.nameSpace === storeEntityType.name;
});
(storeEntityType as breeze.EntityType).getProperties().forEach((storeProperty) => {
//Both NavigationProperty & DataProperty have displayName & nameOnServer properties
var storeDataProperty = <breeze.DataProperty>storeProperty;
var extProperty;
if (extEntityType) {
extProperty = extEntityType.propertiesExtented.find((extendedProperty) => {
return extendedProperty.name === storeDataProperty.nameOnServer;
});
}
//Smart default: nameOnServer "PascalCaseFieldName" or "camelCaseFieldName" converted to "Upper Case Field Name"
storeDataProperty.displayName = (extProperty && extProperty.displayName)
|| storeDataProperty.nameOnServer.replace(/^./, function (str) {
// first ensure the first character is uppercase
return str.toUpperCase();
// insert a space before all caps, remove first character (added space)
}).replace(/([A-Z])/g, " $1").substring(1);
});
});
như tôi đã nói, điều này chỉ có thể tùy chỉnh thông báo mà tôi đã làm. Nhưng làm cách nào để ghi đè tên hiển thị thuộc tính? Ví dụ: nếu tôi có thuộc tính có tên ProductTitle, tôi muốn% displayName% hiển thị 'tên sản phẩm'. – Sam
Sai lầm của tôi, tôi nên đọc bài của bạn cẩn thận hơn. Tôi đã cập nhật câu trả lời ở trên. –
tuyệt vời, đó là những gì tôi cần! Cảm ơn rất nhiều ! – Sam