diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp
index 2fd79715e1463505d868249e46098e9f0465cdca..93cb5e4e9dd56bb880c3f1341cfc079f4fc61cc4 100644
--- a/src/quick/items/qquickitemview.cpp
+++ b/src/quick/items/qquickitemview.cpp
@@ -273,9 +273,13 @@ QVariant QQuickItemView::model() const
     return d->modelVariant;
 }
 
-void QQuickItemView::setModel(const QVariant &model)
+void QQuickItemView::setModel(const QVariant &m)
 {
     Q_D(QQuickItemView);
+    QVariant model = m;
+    if (model.userType() == qMetaTypeId<QJSValue>())
+        model = model.value<QJSValue>().toVariant();
+
     if (d->modelVariant == model)
         return;
     if (d->model) {
diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp
index 825845eca927c6bf391292f64a44c7908e948362..6cf3e33de93dc525800297e235a14ae03cb70b46 100644
--- a/src/quick/items/qquickpathview.cpp
+++ b/src/quick/items/qquickpathview.cpp
@@ -607,9 +607,13 @@ QVariant QQuickPathView::model() const
     return d->modelVariant;
 }
 
-void QQuickPathView::setModel(const QVariant &model)
+void QQuickPathView::setModel(const QVariant &m)
 {
     Q_D(QQuickPathView);
+    QVariant model = m;
+    if (model.userType() == qMetaTypeId<QJSValue>())
+        model = model.value<QJSValue>().toVariant();
+
     if (d->modelVariant == model)
         return;
 
diff --git a/src/quick/items/qquickrepeater.cpp b/src/quick/items/qquickrepeater.cpp
index 8e13947d781fdc4e9aa0bf5b5f75f04cd46e465a..e2a30438574694af7656fe2272a40a550ffa355d 100644
--- a/src/quick/items/qquickrepeater.cpp
+++ b/src/quick/items/qquickrepeater.cpp
@@ -183,9 +183,13 @@ QVariant QQuickRepeater::model() const
     return d->dataSource;
 }
 
-void QQuickRepeater::setModel(const QVariant &model)
+void QQuickRepeater::setModel(const QVariant &m)
 {
     Q_D(QQuickRepeater);
+    QVariant model = m;
+    if (model.userType() == qMetaTypeId<QJSValue>())
+        model = model.value<QJSValue>().toVariant();
+
     if (d->dataSource == model)
         return;
 
diff --git a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp
index b65aad543df5600c017f942b822bef387dfef2f9..123d7f503225ddfc96d3c620e5271fe06ba85930 100644
--- a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp
+++ b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp
@@ -204,6 +204,8 @@ private slots:
     void displayMargin();
     void negativeDisplayMargin();
 
+    void jsArrayChange();
+
 private:
     QList<int> toIntList(const QVariantList &list);
     void matchIndexLists(const QVariantList &indexLists, const QList<int> &expectedIndexes);
@@ -6430,6 +6432,33 @@ void tst_QQuickGridView::negativeDisplayMargin()
     delete window;
 }
 
+void tst_QQuickGridView::jsArrayChange()
+{
+    QQmlEngine engine;
+    QQmlComponent component(&engine);
+    component.setData("import QtQuick 2.4; GridView {}", QUrl());
+
+    QScopedPointer<QQuickGridView> view(qobject_cast<QQuickGridView *>(component.create()));
+    QVERIFY(!view.isNull());
+
+    QSignalSpy spy(view.data(), SIGNAL(modelChanged()));
+    QVERIFY(spy.isValid());
+
+    QJSValue array1 = engine.newArray(3);
+    QJSValue array2 = engine.newArray(3);
+    for (int i = 0; i < 3; ++i) {
+        array1.setProperty(i, i);
+        array2.setProperty(i, i);
+    }
+
+    view->setModel(QVariant::fromValue(array1));
+    QCOMPARE(spy.count(), 1);
+
+    // no change
+    view->setModel(QVariant::fromValue(array2));
+    QCOMPARE(spy.count(), 1);
+}
+
 QTEST_MAIN(tst_QQuickGridView)
 
 #include "tst_qquickgridview.moc"
diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
index 5122b6aa388aa13ad74af7b83be20e95e2ce4564..9e8a813d5401d358a7095b4bfb78cd3081b6e1e7 100644
--- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
+++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
@@ -239,6 +239,8 @@ private slots:
     void QTBUG_39492_data();
     void QTBUG_39492();
 
+    void jsArrayChange();
+
 private:
     template <class T> void items(const QUrl &source);
     template <class T> void changed(const QUrl &source);
@@ -7945,6 +7947,33 @@ void tst_QQuickListView::QTBUG_39492()
     releaseView(window);
 }
 
+void tst_QQuickListView::jsArrayChange()
+{
+    QQmlEngine engine;
+    QQmlComponent component(&engine);
+    component.setData("import QtQuick 2.4; ListView {}", QUrl());
+
+    QScopedPointer<QQuickListView> view(qobject_cast<QQuickListView *>(component.create()));
+    QVERIFY(!view.isNull());
+
+    QSignalSpy spy(view.data(), SIGNAL(modelChanged()));
+    QVERIFY(spy.isValid());
+
+    QJSValue array1 = engine.newArray(3);
+    QJSValue array2 = engine.newArray(3);
+    for (int i = 0; i < 3; ++i) {
+        array1.setProperty(i, i);
+        array2.setProperty(i, i);
+    }
+
+    view->setModel(QVariant::fromValue(array1));
+    QCOMPARE(spy.count(), 1);
+
+    // no change
+    view->setModel(QVariant::fromValue(array2));
+    QCOMPARE(spy.count(), 1);
+}
+
 QTEST_MAIN(tst_QQuickListView)
 
 #include "tst_qquicklistview.moc"
diff --git a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp
index 0e9994899f9d1e9567af9a6bccfc71c783d34231..992b2347dd2a95e2c4d9984f7fca6d7a0361f439 100644
--- a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp
+++ b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp
@@ -139,6 +139,7 @@ private slots:
     void changePathDuringRefill();
     void nestedinFlickable();
     void flickableDelegate();
+    void jsArrayChange();
 };
 
 class TestObject : public QObject
@@ -2290,6 +2291,33 @@ void tst_QQuickPathView::flickableDelegate()
     QCOMPARE(moveStartedSpy.count(), 0);
 }
 
+void tst_QQuickPathView::jsArrayChange()
+{
+    QQmlEngine engine;
+    QQmlComponent component(&engine);
+    component.setData("import QtQuick 2.4; PathView {}", QUrl());
+
+    QScopedPointer<QQuickPathView> view(qobject_cast<QQuickPathView *>(component.create()));
+    QVERIFY(!view.isNull());
+
+    QSignalSpy spy(view.data(), SIGNAL(modelChanged()));
+    QVERIFY(spy.isValid());
+
+    QJSValue array1 = engine.newArray(3);
+    QJSValue array2 = engine.newArray(3);
+    for (int i = 0; i < 3; ++i) {
+        array1.setProperty(i, i);
+        array2.setProperty(i, i);
+    }
+
+    view->setModel(QVariant::fromValue(array1));
+    QCOMPARE(spy.count(), 1);
+
+    // no change
+    view->setModel(QVariant::fromValue(array2));
+    QCOMPARE(spy.count(), 1);
+}
+
 QTEST_MAIN(tst_QQuickPathView)
 
 #include "tst_qquickpathview.moc"
diff --git a/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp b/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp
index 1396dd4783700c2235f6c2ffda8eb71969279903..258eaee981746ea8f57409fec9768fcd7b1a08be 100644
--- a/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp
+++ b/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp
@@ -72,6 +72,7 @@ private slots:
     void dynamicModelCrash();
     void visualItemModelCrash();
     void invalidContextCrash();
+    void jsArrayChange();
 };
 
 class TestObject : public QObject
@@ -779,6 +780,33 @@ void tst_QQuickRepeater::invalidContextCrash()
     root.reset(0);
 }
 
+void tst_QQuickRepeater::jsArrayChange()
+{
+    QQmlEngine engine;
+    QQmlComponent component(&engine);
+    component.setData("import QtQuick 2.4; Repeater {}", QUrl());
+
+    QScopedPointer<QQuickRepeater> repeater(qobject_cast<QQuickRepeater *>(component.create()));
+    QVERIFY(!repeater.isNull());
+
+    QSignalSpy spy(repeater.data(), SIGNAL(modelChanged()));
+    QVERIFY(spy.isValid());
+
+    QJSValue array1 = engine.newArray(3);
+    QJSValue array2 = engine.newArray(3);
+    for (int i = 0; i < 3; ++i) {
+        array1.setProperty(i, i);
+        array2.setProperty(i, i);
+    }
+
+    repeater->setModel(QVariant::fromValue(array1));
+    QCOMPARE(spy.count(), 1);
+
+    // no change
+    repeater->setModel(QVariant::fromValue(array2));
+    QCOMPARE(spy.count(), 1);
+}
+
 QTEST_MAIN(tst_QQuickRepeater)
 
 #include "tst_qquickrepeater.moc"