Skip to content

should fix #660 #671

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
},
"name": "noscript",
"description": "JavaScript MVC framework",
"version": "0.8.15",
"version": "0.8.15-fix-660",
"homepage": "https://github.com/yandex-ui/noscript",
"repository": {
"type": "git",
Expand Down
2 changes: 1 addition & 1 deletion src/ns.version.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// DO NOT CHANGE MANUALLY (use Makefile)
ns.VERSION = '0.8.15';
ns.VERSION = '0.8.15-fix-660';
// DO NOT CHANGE MANUALLY
27 changes: 19 additions & 8 deletions src/ns.view.js
Original file line number Diff line number Diff line change
Expand Up @@ -1201,12 +1201,9 @@
* @private
*/
ns.View.prototype._updateHTML = function(node, updateOptions, events) {
// FIXME nop@: Велик могучим русский языка!
// Падежи не сходятся вообще :(
//
// при обработке toplevel-view надо скопировать первоначальные updateOptions
// инчае, при обновлении параллельных веток дерева, toplevel оказажется только первая
// и, соответственно, DOM-надо обновиться только у нее
// иначе, при обновлении параллельных веток дерева, toplevel === true будет только у первой и,
// соответственно, DOM-нода обновится только у нее
// {
// "my-root-view1": {/* tree 1 */},
// "my-root-view2": {/* tree 2 */}
Expand All @@ -1219,13 +1216,26 @@
options_next = updateOptions;
}

var viewNode;
var extractedViewNode = node ? this._extractNode(node) : null;
var viewWasInvalid = !this.isValid();

var viewNode;
// Особый случай, когда нужно обновить ноду вида:
// обновилась нода родительского вида, при этом текущий вид был валиден.
// @see #660
var viewNodeWasInvalid = (
this.isValid() &&
this.node &&
extractedViewNode &&
extractedViewNode !== this.node &&
updateOptions.parent_added &&
!updateOptions.toplevel
);

// Если блок уже валидный, ничего не делаем, идем ниже по дереву.
if ( viewWasInvalid ) {
if ( viewWasInvalid || viewNodeWasInvalid ) {
// Ищем новую ноду блока.
viewNode = this._extractNode(node);
viewNode = extractedViewNode;
ns.View.assert(!!viewNode, 6, [this.id]);

// Обновляем весь блок.
Expand Down Expand Up @@ -1279,6 +1289,7 @@

// Т.к. мы, возможно, сделали replaceNode, то внутри node уже может не быть
// никаких подблоков. В этом случае, нужно брать viewNode.
// TODO фалбек на node - совсем не понятно, зачем :/
viewNode = viewNode || node;

// Рекурсивно идем вниз по дереву, если не находимся в async-режиме
Expand Down
40 changes: 39 additions & 1 deletion test/spec/ns.view.js
Original file line number Diff line number Diff line change
Expand Up @@ -1155,7 +1155,7 @@ describe('ns.View', function() {

});

describe('updateHTML', function() {
describe('#_updateHTML()', function() {

describe('redraw async view with child depens on same model', function() {

Expand Down Expand Up @@ -1389,6 +1389,44 @@ describe('ns.View', function() {

});

describe('обновление ноды валидного вида, вложенного в бокс', function() {
beforeEach(function() {
ns.View.define('view-1');
this.view = ns.View.create('view-1');
this.view.node = document.createElement('div');
this.view.asyncState = false;

this.newViewNode = document.createElement('div');
this.nodeFromUpdate = document.createElement('div');

this.sinon.stub(this.view, '_extractNode').withArgs(this.nodeFromUpdate).returns(this.newViewNode);
this.sinon.stub(this.view, 'isValid').returns(true);
this.sinon.stub(this.view, 'isLoading').returns(false);
this.sinon.stub(this.view, 'isOk').returns(true);

this.sinon.stub(this.view, '__onHide');
this.sinon.stub(this.view, '__onHtmldestroy');
this.sinon.stub(this.view, '_htmlinit');
this.sinon.stub(this.view, '_saveModelsVersions');
this.sinon.stub(this.view, '_show');
this.sinon.stub(this.view, '_apply');
this.sinon.stub(this.view, '_setNode');
});

it('должен подновить ноду валидного вида', function() {
var updateOptions = { toplevel: false, parent_added: true };
var events = {
'ns-view-touch': []
};

this.view._updateHTML(this.nodeFromUpdate, updateOptions, events);

expect(this.view._setNode)
.to.have.callCount(1)
.and
.to.be.calledWithExactly(this.newViewNode);
});
});
});

describe('ns.View update after model destruction', function() {
Expand Down