これまでのところ、非常にうまく機能しているシングル ページ アプリケーションがありますが、理解できない問題に遭遇しました。私はそよ風を使用して、テーブルに表示されるプロジェクトのリストを作成しています。実際に必要なものよりもはるかに多くの情報があるため、データの投影を行っています。エンティティに計算されたノックアウトを追加したい。これを達成するために、私は登録し、エンティティコンストラクターをそのように...
metadataStore.registerEntityTypeCtor(entityNames.project, function () { this.isPartial = false; }, initializeProject);
initializeProject 関数は、プロジェクト内の値の一部を使用して、計算対象の値を決定します。たとえば、Project.Type == "P" の場合、rowClass は = "Red" にする必要があります。
私が抱えている問題は、たまたまキーである ProjNum を除いて、Project のすべてのプロパティが null であることです。問題は、他のタイプの他の初期化子を登録していて、正常に機能するため、投影を行っているためだと思います。これを機能させる方法はありますか?
編集:明確にするために、もう少し詳細を追加すると思いました。Chrome で JavaScript デバッガーを使用してプロパティに問い合わせると、すべてのプロパティの _latestValue が null になります。設定される唯一のプロパティは、エンティティ キーでもある ProjNum です。
EDIT2:これは、投影を行うクライアント側のコードです
var getProjectPartials = function (projectObservable, username, forceRemote) {
var p1 = new breeze.Predicate("ProjManager", "==", username);
var p2 = new breeze.Predicate("ApprovalStatus", "!=", "X");
var p3 = new breeze.Predicate("ApprovalStatus", "!=", "C");
var select = 'ProjNum,Title,Type,ApprovalStatus,CurrentStep,StartDate,ProjTargetDate,CurTargDate';
var isQaUser = cookies.getCookie("IsQaUser");
if (isQaUser == "True") {
p1 = new breeze.Predicate("QAManager", "==", username);
select = select + ',QAManager';
} else {
select = select + ',ProjManager';
}
var query = entityQuery
.from('Projects')
.where(p1.and(p2).and(p3))
.select(select);
if (!forceRemote) {
var p = getLocal(query);
if (p.length > 1) {
projectObservable(p);
return Q.resolve();
}
}
return manager.executeQuery(query).then(querySucceeded).fail(queryFailed);
function querySucceeded(data) {
var list = partialMapper.mapDtosToEntities(
manager,
data.results,
model.entityNames.project,
'ProjNum'
);
if (projectObservable) {
projectObservable(list);
}
log('Retrieved projects using breeze', data, true);
}
};
および partialMapper.mapDtosToEntities 関数のコード。
var defaultExtension = { isPartial: true };
function mapDtosToEntities(manager,dtos,entityName,keyName,extendWith) {
return dtos.map(dtoToEntityMapper);
function dtoToEntityMapper(dto) {
var keyValue = dto[keyName];
var entity = manager.getEntityByKey(entityName, keyValue);
if (!entity) {
extendWith = $.extend({}, extendWith || defaultExtension);
extendWith[keyName] = keyValue;
entity = manager.createEntity(entityName, extendWith);
}
mapToEntity(entity, dto);
entity.entityAspect.setUnchanged();
return entity;
}
function mapToEntity(entity, dto) {
for (var prop in dto) {
if (dto.hasOwnProperty(prop)) {
entity[prop](dto[prop]);
}
}
return entity;
}
}
EDIT3:それは私の間違いだったようです。initializeProject を詳しく調べたところ、エラーが見つかりました。以下は、修正前の関数の外観です。
function initializeProject(project) {
project.rowClass = ko.computed(function() {
if (project.Type == "R") {
return "project-list-item info";
} else if (project.Type == "P") {
return "project-list-item error";
}
return "project-list-item";
});
}
問題は project.Type にありました。これは監視可能であるため、project.Type() を使用する必要がありました。このプロジェクトを開始して以来、私が何度も犯してきた愚かな間違いです。
EDIT4: initializeProject の内部では、機能している部分と機能していない部分があります。project.ProjTargetDate() にアクセスしようとすると、project.StartDate() と同じように null が返されます。Null 値が原因で、これらの日付を使用してプロジェクトがいつ遅れているかを判断しているときに、モーメント ライブラリからエラーがスローされます。クライアントクエリからの選択と部分エンティティマッパーへの呼び出しを削除しようとしましたが、それを行うとすべて正常に機能しました。