禁用 iframe src 的监听器
Disable the listener to src of iframe
我的模板中有一个 iframe,src
指的是物理 html 文件。
<iframe id="myiframe" src="{{src}}">
</iframe>
在控制器中,不时调用一个函数rewriteAllFiles
来更新物理html, js, css
文件。它首先删除所有旧文件,然后写入新文件,然后刷新 iframe。
var refreshIframe = function () {
var iframe = document.getElementById('myiframe');
iframe.src = iframe.src;
console.log("refreshIframe, done")
}
rewriteAllFiles = function (path, files) {
return $http.post('/emptyDir', { dir: prefix + idP + "/", path: path })
.then(function (res) {
console.log("rewriteAllFiles /emptyDir, done");
return $http.post('/writeFiles', { dir: prefix + idP + "/", files: files })
.then(function (res) {
console.log("rewriteAllFiles /writeFiles, done");
refreshIframe();
return res
})
})
}
$scope.$watch(... {
return rewriteAllFiles($location.path(), $scope.files);
})
我的测试显示有时它可以正常工作,但有时它会给出以下日志:
rewriteAllFiles /emptyDir, done
GET http://localhost:3000/tmp/P0L7JSEOWux3YE1FAAA6/index.html 404 (Not Found)
rewriteAllFiles /writeFiles, done
refreshIframe, done
所以似乎是在删除旧文件之后和写入新文件之前,html 模板尝试加载 src
,当然导致文件暂时不可用。我没有为 src
设置监听器,有谁知道 src
的监听器在哪里以及如何禁用它?
编辑1:这里是服务器端writeFiles
的代码:
router.post('/writeFiles', function (req, res, next) {
var dir = req.body.dir, files = req.body.files;
var fs = require('fs');
var queue = files.map(function (file) {
return new Promise(function (resolve, reject) {
fs.writeFile(dir + file.name, file.body, function (err) {
if (err) return reject(err);
console.log(dir + file.name + " is written");
resolve(file);
})
})
});
Promise.all(queue)
.then(function(files) {
console.log("All files have been successfully written");
res.json(dir);
})
.catch(function (err) {
return console.log(err)
});
});
您可以试试{{::src}}。它只被渲染一次。
我意识到它与控制器中的另一行代码有关。
$scope.src = getSrc() // getSrc(); returns the right html link initiated by a resolving
$scope.$watch(... {
return rewriteAllFiles($location.path(), $scope.files);
})
当我们加载模板时,上面的代码有可能$scope.src = getSrc()
在旧文件被删除之后和新文件写入之前执行,这会引发Not Found
错误。
所以我们只需要通过then
确定执行顺序即可;以下代码有效:
$scope.$watch(... {
return rewriteAllFiles($location.path(), $scope.files)
.then(function () {
$scope.src = getSrcP();
});
});
我的模板中有一个 iframe,src
指的是物理 html 文件。
<iframe id="myiframe" src="{{src}}">
</iframe>
在控制器中,不时调用一个函数rewriteAllFiles
来更新物理html, js, css
文件。它首先删除所有旧文件,然后写入新文件,然后刷新 iframe。
var refreshIframe = function () {
var iframe = document.getElementById('myiframe');
iframe.src = iframe.src;
console.log("refreshIframe, done")
}
rewriteAllFiles = function (path, files) {
return $http.post('/emptyDir', { dir: prefix + idP + "/", path: path })
.then(function (res) {
console.log("rewriteAllFiles /emptyDir, done");
return $http.post('/writeFiles', { dir: prefix + idP + "/", files: files })
.then(function (res) {
console.log("rewriteAllFiles /writeFiles, done");
refreshIframe();
return res
})
})
}
$scope.$watch(... {
return rewriteAllFiles($location.path(), $scope.files);
})
我的测试显示有时它可以正常工作,但有时它会给出以下日志:
rewriteAllFiles /emptyDir, done
GET http://localhost:3000/tmp/P0L7JSEOWux3YE1FAAA6/index.html 404 (Not Found)
rewriteAllFiles /writeFiles, done
refreshIframe, done
所以似乎是在删除旧文件之后和写入新文件之前,html 模板尝试加载 src
,当然导致文件暂时不可用。我没有为 src
设置监听器,有谁知道 src
的监听器在哪里以及如何禁用它?
编辑1:这里是服务器端writeFiles
的代码:
router.post('/writeFiles', function (req, res, next) {
var dir = req.body.dir, files = req.body.files;
var fs = require('fs');
var queue = files.map(function (file) {
return new Promise(function (resolve, reject) {
fs.writeFile(dir + file.name, file.body, function (err) {
if (err) return reject(err);
console.log(dir + file.name + " is written");
resolve(file);
})
})
});
Promise.all(queue)
.then(function(files) {
console.log("All files have been successfully written");
res.json(dir);
})
.catch(function (err) {
return console.log(err)
});
});
您可以试试{{::src}}。它只被渲染一次。
我意识到它与控制器中的另一行代码有关。
$scope.src = getSrc() // getSrc(); returns the right html link initiated by a resolving
$scope.$watch(... {
return rewriteAllFiles($location.path(), $scope.files);
})
当我们加载模板时,上面的代码有可能$scope.src = getSrc()
在旧文件被删除之后和新文件写入之前执行,这会引发Not Found
错误。
所以我们只需要通过then
确定执行顺序即可;以下代码有效:
$scope.$watch(... {
return rewriteAllFiles($location.path(), $scope.files)
.then(function () {
$scope.src = getSrcP();
});
});