Repeater控件中图片占位符的图片绑定失效问题排查
Hey, let's figure out why your Repeater isn't showing those images—there are a few key issues in your code that are causing this:
1. Critical Syntax Error in Observable Setter
You have a broken line where you try to update the observable:
imagesource.set = ("images", imageList);
This is invalid syntax. The set method on an observable (created via fromObject) needs to be called as a function, not assigned. You can either fix it to:
imagesource.set("images", imageList);
Or even simpler, directly assign the property since fromObject makes it observable:
imagesource.images = imageList;
2. Missing photoevidence Field (Images Are Hidden!)
Your Image template uses:
visibility="{{photoevidence === 'y' ? 'visible' : 'collapse'}}"
But when you push items to imageList, you don't include the photoevidence property. Every image is being collapsed automatically! Add this field to each item:
imageList.push({ localurl: rows[row][0], filename: rows[row][2], photoevidence: 'y' // 👈 This makes the image visible });
3. Typo in Camera Options
You wrote keepAspectRation (missing an a) in your camera options—this might cause unexpected behavior with image sizing:
var options = {saveToGallery: true, keepAspectRatio: true, height: 1024 }; // Fixed spelling
4. Redundant Variable Definitions & Async Nesting
You repeat livesite multiple times in nested scopes, and your async code is deeply nested (making it hard to debug). Switching to async/await will clean this up significantly.
Fixed Code Example
Here's your updated takePic function with all the fixes applied:
const camera = require("nativescript-camera"); const imageSourceModule = require("nativescript-image-source"); const filesystem = require("nativescript-file-system"); const appSettings = require("nativescript-app-settings"); const { fromObject } = require("tns-core-modules/data/observable"); const sqlite = require("nativescript-sqlite"); exports.takePic = async function(args){ try { const page = args.object; // Request camera permissions first await camera.requestPermissions(); const livesite = appSettings.getString("livesite"); const whichcamera = args.object; const options = { saveToGallery: true, keepAspectRatio: true, height: 1024 }; const source = new imageSourceModule.ImageSource(); // Capture photo const imageAsset = await camera.takePicture(options); const imageSource = await source.fromAsset(imageAsset); // Open database connection const auditDB = await new sqlite("my.db"); // Calculate next image count const tempfilename = `${livesite}-${whichcamera.qid}-`; const rows = await auditDB.all(`SELECT filename FROM images WHERE filename LIKE '${tempfilename}%'`); const imageCount = rows.length === 0 ? 1 : rows.length + 1; // Save image to documents folder const folder = filesystem.knownFolders.documents(); const filename = `${livesite}-${whichcamera.qid}-${imageCount}.jpg`; const imgPath = filesystem.path.join(folder.path, filename); const saved = imageSource.saveToFile(imgPath, "jpg"); if (saved) { // Insert record into database const liveaudit = appSettings.getString("liveaudit"); await auditDB.execSQL( "INSERT INTO images (localurl,remoteurl,syncd,siteid,filename,question) VALUES(?,?,?,?,?,?)", [imgPath, '-', 'n', livesite, filename, whichcamera.qid] ); // Fetch updated image list const imageRows = await auditDB.all(`SELECT localurl,filename FROM images WHERE filename LIKE '${tempfilename}%'`); const imageList = imageRows.map(row => ({ localurl: row[0], filename: row[1], photoevidence: 'y' })); // Update Repeater binding const imagesource = fromObject({ images: imageList }); const imageholder = page.getViewById(`repeat_${whichcamera.id}`); imageholder.bindingContext = imagesource; } } catch (err) { if (err.message.includes("permission")) { alert("You must allow this app access to the camera and your photos library."); } else { alert(`Error: ${err.message}`); } } };
Quick Additional Checks
- Repeater ID Matching: Ensure the
idof your Repeater in XML ({{ repeaterphotoid }}) exactly matchesrepeat_${whichcamera.id}(e.g., if your button ID iscamera1, the Repeater ID should berepeat_camera1). - Permissions: Double-check that you've added camera and storage permissions to
AndroidManifest.xml(Android) andInfo.plist(iOS)—without these, photos won't save or load.
内容的提问来源于stack exchange,提问作者Frank Nicklin

